Как удалить строку запроса и получить только URL?


201

Я использую PHP для создания URL текущей страницы. Иногда URL-адреса в виде

www.mydomian.com/myurl.html?unwantedthngs

запрашиваются. Я хочу удалить ?и все, что следует за ним (querystring), так что результирующий URL становится:

www.mydomain.com/myurl.html

Мой текущий код такой:

<?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;
}
?>

8
Кстати, это называется «строка запроса».
— Эван Мулавски

Ответы:


578

Вы можете использовать, strtokчтобы получить строку до первого появления?

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

strtok()представляет собой наиболее краткую технику для непосредственного извлечения подстроки перед ?строкой запроса. explode()менее прямой, потому что он должен создать потенциально двухэлементный массив, по которому должен быть получен доступ к первому элементу.

Некоторые другие методы могут сломаться, если строка запроса отсутствует, или потенциально могут изменить другие / непреднамеренные подстроки в URL - этих методов следует избегать.

Демонстрация :

$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";
}

Вывод:

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
)
---

24
+1 за непосредственное использование $ _SERVER вместо пересоздания URL только для повторного его анализа. дал бы еще +1, если это возможно, для краткости.
— ericsoco

8
К сожалению, отмените эти аргументы для explode (), разделитель идет первым. array_shift(explode('?',$_SERVER["REQUEST_URI"]))
— здесь

13
Это не возвращает bool (false), если? отсутствует в строке, она возвращает строку.
— Бен С

4
Отлично! .. Он все еще возвращает URL, даже если ?его нет.
— Харикришнан

1
@sepehr, я просто не вижу смысла не использовать функцию, которая делает именно то, что вам нужно, использовать другую и анализировать ее результат (т.е. получить [0] после взрыва) (если, конечно, нет особой причины, например, повышения производительности отсутствие ненужной зависимости и т. д.).
— RiaD

66

Использовать руководство по PHP - parse_url () чтобы получить нужные вам части.

Изменить (пример использования для @Navi Gamage)

Вы можете использовать это так:

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

    return $constructed_url;
}

?>

Изменить (второй полный пример):

Обновленная функция, чтобы убедиться, что схема будет присоединена и никакие уведомления не появляются:

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.mydomian.com/myurl.html?unwan=abc',
    'http://www.mydomian.com/myurl.html',
    'http://www.mydomian.com',
    'https://mydomian.com/myurl.html?unwan=abc&ab=1'
);

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

Вернется:

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

Это результат передачи примера URL через parse_url () без второго параметра (только для пояснения).

И это окончательный вывод после построения URL с использованием:

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

Вывод:

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

Я прочитал это .. Я немного запутался, потому что если вы новичок в php. Можете ли вы помочь мне с приведенным выше кодом php?
— Navi Gamage

я добавил этот код после строки 9 $ pageURL = substr ($ pageURL, 0, strrpos ($ pageURL, "?"));
— Navi Gamage

Он очищает раздел запроса в URL-адресе ...> www.mydomain.com/myurl.html?unwantedthings результат - все в порядке! > www.mydomian.com/myurl.html Готово ... Но когда оно приходит с нормальным URL-адресом> www.mydomain.com/myurl.html результат - ничто .. Пусто
— Navi Gamage

strrpos () в 'www.mydomain.com/myurl.html' вернет 0 (FALSE приведен к логическому значению, чтобы быть более правильным), так что ваш substr будет пустым. Используйте один : substr () ИЛИ parse_url (), потому что использование обоих не имеет смысла;)
— veritas

Я имел в виду ЛОЖНОЕ приведение к int; D
— veritas

54

лучшее решение:

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

Не нужно включать ваш http://domain.com в ваш, если вы отправляете форму на тот же домен.


Обратите внимание, что parse_url ожидает абсолютный URL, поэтому в некоторых случаях вы получите неверные результаты, например, если ваш REQUEST_URL начинается с нескольких последовательных слешей. Они будут интерпретироваться как относительный к протоколу URI.
— NikiC

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

Ребята, отвечающие на ваши ответы, я сделал .. спасибо за вашу помощь. Он очищает раздел запросов в URL ...
— Navi Gamage

> www.mydomain.com/myurl.html?unwantedthings результат в порядке! > www.mydomian.com/myurl.html Готово ... Но когда оно приходит с нормальным URL-адресом> www.mydomain.com/myurl.html результат - ничто .. Пусто
— Navi Gamage

Новый код php code <? 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"]; $ pageURL = substr ($ pageURL, 0, strrpos ($ pageURL, "?")); } return $ pageURL; }?>code
— Navi Gamage

2
Я думаю, что это довольно милое и простое решение проблемы. Нет необходимости загружать расширения или функции. Я использовал это, чтобы получить текущее имя файла. $ base = basename ($ _ SERVER ['REQUEST_URI']); $ page = substr ($ base, 0, strrpos ($ base, "?"));
— Роб

Как заявил Navi, этот ответ не является надежным. 3v4l.org/nhVii Если в URL отсутствует строка запроса, весь URL удаляется! Этот метод не учитывает URL-компоненты. Этот ответ нецелесообразен.
— mickmackusa

9

Самый простой способ

$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

Я не согласен с тем, что это самый простой способ. Нет, жирный текст не делает ваше утверждение более убедительным. Этот ответ не хватает объяснения.
— mickmackusa

@mickmackusa Не могли бы вы разработать свой комментарий? Где мне нужно объяснить мой ответ? Я буду благодарен вам.
— Мукеш Саксена

Все ответы на Stackoverflow должны включать объяснение того, как работает решение и почему вы считаете, что это идеальный метод. Ссылки на документацию также приветствуются. Я полностью понимаю ваше решение, но другой исследователь не может. Ответы только на код имеют низкую ценность в Stackoverflow, потому что они очень мало делают для обучения / расширения возможностей тысяч будущих исследователей. О том, чтобы не быть самым простым - 3v4l.org/RE0GD будет более простой версией вашего ответа, потому что в нем меньше объявленных переменных и выполняется только одна замена вместо двух. Принятый ответ является самым простым из всех.
— mickmackusa

Другое отличие состоит в том, что принятый ответ также заботится о возможном фрагменте, но ваш не будет. 3v4l.org/ERr4V или хуже, он может изменить URL слева от строки
— mickmackusa

7

Вам понадобится по крайней мере PHP версии 5.4 для реализации этого решения, без разбивки на переменные в одной строке и конкатенации на следующей, но проще всего будет один вкладыш:

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

Переменные сервера: http://php.net/manual/en/reserved.variables.server.php
Разыменование массива: https://wiki.php.net/rfc/functionarraydereferencing


4

Вы можете использовать встроенную функцию parse_url следующим образом:

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

2

Можешь попробовать:

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

2

Если вы хотите получить путь запроса ( подробнее ):

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

Если вы хотите удалить запрос и (и, возможно, фрагмент также):

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);

1

Чтобы удалить строку запроса из URI запроса, замените строку запроса пустой строкой:

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

Я думаю, что будет потенциальная проблема с www.example.com/myurl.html?.
— Эрли

1

Поскольку я работаю как с относительными, так и с абсолютными URL-адресами, я обновил решение Veritas, как показано ниже.
Вы можете попробовать себя здесь: 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;
}

1

может также использовать следующее согласно комментарию php вручную

$_SERVER['REDIRECT_URL']

Пожалуйста, обратите внимание, что это работает только для определенной среды PHP и следуйте ниже комментарию на этой странице для получения дополнительной информации;

Цель: URL-путь к текущему файлу PHP, path-info - N / A, исключая строку запроса URL. Включает ведущий слеш.

Предостережение: это перед перезаписью URL-адреса (то есть в соответствии с исходным URL-адресом вызова).

Предостережение: Не установлен во всех средах PHP, и определенно только в тех, где перезаписывается URL.

Работает в веб-режиме: Да

Работает в режиме CLI: Нет


0

Попробуй это

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

0

Предполагая, что вы все еще хотите получить URL без аргументов запроса (если они не заданы), просто используйте сокращение if для проверки strpos:

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

0

Вот простое решение, если вы используете Laravel:

Str::before($request->getRequestUri(), '?')

-3

Попробуй это:

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

или

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

1
Извините, но это неправильно - URI может быть переписан htaccess - это приведет к возвращению имени скрипта, но не текущего URI.
— Гексодус

Опасно, как это может быть подделано.
— Тим

подтвердить неверно. Предположим, вы пишете proxy.php, который перенаправляет .htaccess из запросов на различные ресурсы, такие как index.php, Prices.php, about.php, и динамически создает представление для запрошенного имени. если вы используете это, скрипт всегда будет видеть proxy.php, а не требуемый запрошенный ресурс, который он хочет построить.
— Дмитрий
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.