Navi Gamage
Navi Gamage

Reputation: 2783

How to remove the querystring and get only the URL?

I'm using PHP to build the URL of the current page. Sometimes, URLs in the form of

www.example.com/myurl.html?unwantedthngs

are requested. I want to remove the ? and everything that follows it (querystring), such that the resulting URL becomes:

www.example.com/myurl.html

My current code is this:

<?php
function curPageURL() {
    $pageURL = 'http';
    if ($_SERVER["HTTPS"] == "on") {
        $pageURL .= "s";
    }
    $pageURL .= "://";
    if ($_SERVER["SERVER_PORT"] != "80") {
        $pageURL .= $_SERVER["SERVER_NAME"] . ":" .
            $_SERVER["SERVER_PORT"] . $_SERVER["REQUEST_URI"];
    } else {
        $pageURL .= $_SERVER["SERVER_NAME"] . $_SERVER["REQUEST_URI"];
    }
    return $pageURL;
}
?>

Upvotes: 257

Views: 232199

Answers (17)

redanimalwar
redanimalwar

Reputation: 1503

I am surprised that this does not have an answer to do this really safe and clean, so let me do that. This checks if the URL can be parsed, and it keeps the #hash in the URL. strtok won't do that.

<?php

echo remove_url_query('https://foo.bar?arg1=alpha&arg2=beta#hash'); # https://foo.bar#hash

function remove_url_query( string $url ): ?string {

    $parsed_url = parse_url( $url );

    if ( ! $parsed_url ) {
        return null;
    }

    $scheme   = isset( $parsed_url['scheme'] ) ? $parsed_url['scheme'] . '://' : '';
    $host     = isset( $parsed_url['host'] ) ? $parsed_url['host'] : '';
    $port     = isset( $parsed_url['port'] ) ? ':' . $parsed_url['port'] : '';
    $user     = isset( $parsed_url['user'] ) ? $parsed_url['user'] : '';
    $pass     = isset( $parsed_url['pass'] ) ? ':' . $parsed_url['pass'] : '';
    $pass     = ( $user || $pass ) ? "$pass@" : '';
    $path     = isset( $parsed_url['path'] ) ? $parsed_url['path'] : '';
    $fragment = isset( $parsed_url['fragment'] ) ? '#' . $parsed_url['fragment'] : '';

    return "$scheme$user$pass$host$port$path$fragment";
}

Removing the types will make this work and all kinds of outdated PHP versions.

Upvotes: 0

explode('?', $_SERVER['REQUEST_URI'])[0]

Upvotes: 6

kwelsan
kwelsan

Reputation: 1219

Try this

$url_with_querystring = 'www.example.com/myurl.html?unwantedthngs';
$url_data = parse_url($url_with_querystring);
$url_without_querystring = str_replace('?'.$url_data['query'], '', $url_with_querystring);

Upvotes: 0

veritas
veritas

Reputation: 2052

Use PHP Manual - parse_url() to get the parts you need.

Edit (example usage for @Navi Gamage)

You can use it like this:

<?php
function reconstruct_url($url){
    $url_parts = parse_url($url);
    $constructed_url = $url_parts['scheme'] . '://' . $url_parts['host'] . $url_parts['path'];

    return $constructed_url;
}

?>

Edit (second full example):

Updated function to make sure scheme will be attached and none notice msgs appear:

function reconstruct_url($url){
    $url_parts = parse_url($url);
    $constructed_url = $url_parts['scheme'] . '://' . $url_parts['host'] . (isset($url_parts['path'])?$url_parts['path']:'');

    return $constructed_url;
}

$test = array(
    'http://www.example.com/myurl.html?unwan=abc',
    `http://www.example.com/myurl.html`,
    `http://www.example.com`,
    `https://example.com/myurl.html?unwan=abc&ab=1`
);

foreach($test as $url){
    print_r(parse_url($url));
}

Will return:

Array
(
    [scheme] => http
    [host] => www.example.com
    [path] => /myurl.html
    [query] => unwan=abc
)
Array
(
    [scheme] => http
    [host] => www.example.com
    [path] => /myurl.html
)
Array
(
    [scheme] => http
    [host] => www.example.com
)
Array
(
    [path] => example.com/myurl.html
    [query] => unwan=abc&ab=1
)

This is the output from passing example URLs through parse_url() with no second parameter (for explanation only).

And this is the final output after constructing URL using:

foreach($test as $url){
    echo reconstruct_url($url) . '<br/>';
}

Output:

http://www.example.com/myurl.html
http://www.example.com/myurl.html
http://www.example.com
https://example.com/myurl.html

Upvotes: 77

Ludo - Off the record
Ludo - Off the record

Reputation: 5533

best solution:

echo parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);

No need to include your http://example.com in your <form action=""> if you're submitting a form to the same domain.

Upvotes: 72

RiaD
RiaD

Reputation: 47619

You can use strtok to get string before first occurence of ?

$url = strtok($_SERVER["REQUEST_URI"], '?');

strtok() represents the most concise technique to directly extract the substring before the ? in the querystring. explode() is less direct because it must produce a potentially two-element array by which the first element must be accessed.

Some other techniques may break when the querystring is missing or potentially mutate other/unintended substrings in the url -- these techniques should be avoided.

A demonstration:

$urls = [
    'www.example.com/myurl.html?unwantedthngs#hastag',
    'www.example.com/myurl.html'
];

foreach ($urls as $url) {
    var_export(['strtok: ', strtok($url, '?')]);
    echo "\n";
    var_export(['strstr/true: ', strstr($url, '?', true)]); // not reliable
    echo "\n";
    var_export(['explode/2: ', explode('?', $url, 2)[0]]);  // limit allows func to stop searching after first encounter
    echo "\n";
    var_export(['substr/strrpos: ', substr($url, 0, strrpos( $url, "?"))]);  // not reliable; still not with strpos()
    echo "\n---\n";
}

Output:

array (
  0 => 'strtok: ',
  1 => 'www.example.com/myurl.html',
)
array (
  0 => 'strstr/true: ',
  1 => 'www.example.com/myurl.html',
)
array (
  0 => 'explode/2: ',
  1 => 'www.example.com/myurl.html',
)
array (
  0 => 'substr/strrpos: ',
  1 => 'www.example.com/myurl.html',
)
---
array (
  0 => 'strtok: ',
  1 => 'www.example.com/myurl.html',
)
array (
  0 => 'strstr/true: ',
  1 => false,                       // bad news
)
array (
  0 => 'explode/2: ',
  1 => 'www.example.com/myurl.html',
)
array (
  0 => 'substr/strrpos: ',
  1 => '',                          // bad news
)
---

Upvotes: 731

sMyles
sMyles

Reputation: 2666

Assuming you still want to get the URL without the query args (if they are not set), just use a shorthand if statement to check with strpos:

$request_uri = strpos( $_SERVER['REQUEST_URI'], '?' ) !== false ? strtok( $_SERVER["REQUEST_URI"], '?' ) : $_SERVER['REQUEST_URI'];

Upvotes: 0

Muho
Muho

Reputation: 3536

You can use the parse_url build in function like that:

$baseUrl = $_SERVER['SERVER_NAME'] . parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);

Upvotes: 8

Janith Chinthana
Janith Chinthana

Reputation: 3844

could also use following as per the php manual comment

$_SERVER['REDIRECT_URL']

Please note this is working only for certain PHP environment only and follow the bellow comment from that page for more information;

Purpose: The URL path name of the current PHP file, path-info is N/A and excluding URL query string. Includes leading slash.

Caveat: This is before URL rewrites (i.e. it's as per the original call URL).

Caveat: Not set on all PHP environments, and definitely only ones with URL rewrites.

Works on web mode: Yes

Works on CLI mode: No

Upvotes: 2

Mukesh Saxena
Mukesh Saxena

Reputation: 146

Most Easiest Way

$url = 'https://www.youtube.com/embed/ROipDjNYK4k?rel=0&autoplay=1';
$url_arr = parse_url($url);
$query = $url_arr['query'];
print $url = str_replace(array($query,'?'), '', $url);

//output
https://www.youtube.com/embed/ROipDjNYK4k

Upvotes: 9

James Bordine II
James Bordine II

Reputation: 101

You'll need at least PHP Version 5.4 to implement this solution without exploding into a variable on one line and concatenating on the next, but an easy one liner would be:

$_SERVER["HTTP_HOST"].explode('?', $_SERVER["REQUEST_URI"], 2)[0];

Server Variables: http://php.net/manual/en/reserved.variables.server.php
Array Dereferencing: https://wiki.php.net/rfc/functionarraydereferencing

Upvotes: 8

HRALDA
HRALDA

Reputation: 1

Try this:

$urrl=$_SERVER['HTTP_HOST'] . $_SERVER['SCRIPT_NAME']

or

$urrl=$_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF']

Upvotes: -3

trante
trante

Reputation: 33986

Because I deal with both relative and absolute URLs, I updated veritas's solution like the code below.
You can try yourself here: https://ideone.com/PvpZ4J

function removeQueryStringFromUrl($url) {
    if (substr($url,0,4) == "http") {
        $urlPartsArray = parse_url($url);
        $outputUrl = $urlPartsArray['scheme'] . '://' . $urlPartsArray['host'] . ( isset($urlPartsArray['path']) ? $urlPartsArray['path'] : '' );
    } else {
        $URLexploded = explode("?", $url, 2);
        $outputUrl = $URLexploded[0];
    }
    return $outputUrl;
}

Upvotes: 1

user1079877
user1079877

Reputation: 9358

If you want to get request path (more info):

echo parse_url($_SERVER["REQUEST_URI"])['path']

If you want to remove the query and (and maybe fragment also):

function strposa($haystack, $needles=array(), $offset=0) {
        $chr = array();
        foreach($needles as $needle) {
                $res = strpos($haystack, $needle, $offset);
                if ($res !== false) $chr[$needle] = $res;
        }
        if(empty($chr)) return false;
        return min($chr);
}
$i = strposa($_SERVER["REQUEST_URI"], ['#', '?']);
echo strrpos($_SERVER["REQUEST_URI"], 0, $i);

Upvotes: 2

Ryan Prechel
Ryan Prechel

Reputation: 6762

To remove the query string from the request URI, replace the query string with an empty string:

function request_uri_without_query() {
    $result = $_SERVER['REQUEST_URI'];
    $query = $_SERVER['QUERY_STRING'];
    if(!empty($query)) {
        $result = str_replace('?' . $query, '', $result);
    }
    return $result;
}

Upvotes: 1

ysrb
ysrb

Reputation: 6740

You can try:

<?php
$this_page = basename($_SERVER['REQUEST_URI']);
if (strpos($this_page, "?") !== false) $this_page = reset(explode("?", $this_page));
?>

Upvotes: 2

zellio
zellio

Reputation: 32484

$val = substr( $url, 0, strrpos( $url, "?"));

Upvotes: 16

Related Questions