Intereting Posts
Неверный тайм-аут PHP cURL Как установить UTF-8 в конструкторе класса PDO для базы данных PHP PgSQL Laravel – Как использовать класс поставщика? Создание отчета в формате PDF от php Как увеличить мои «продвинутые» знания PHP дальше? (быстро) Внедрение полнофункциональной загрузки мультимедиа в веб-приложении «PDOException» с сообщением «SQLSTATE : общая ошибка: 2014 Не удается выполнить запросы, в то время как другие небуферизованные запросы активны Когда я убираю все входные данные, иногда он оставляет в строке строчки (\) и вставляет их в базу данных. Почему это происходит и как я могу это решить? Возможно ли обновить количество элементов заказа в Magento? Использование PHP 7 с WAMP Методы событий плагина в Virtuemart для статуса заказа Блокировать определенный IP-блок с моего сайта в PHP Выпадающий список из столбца MySQL с использованием mysqli Обновление PHP XSLT-процессора до XSLT 2.0 Проблема с загрузкой изображения php: неопределенный индекс

Красивый способ удаления GET-переменных с помощью PHP?

У меня есть строка с полным URL, включая переменные GET. Каков наилучший способ удалить переменные GET? Есть ли хороший способ удалить только один из них?

Это код, который работает, но не очень красив (я думаю):

$current_url = explode('?', $current_url); echo $current_url[0]; 

Приведенный выше код просто удаляет все переменные GET. URL-адрес в моем случае создан из CMS, поэтому мне не нужна информация о переменных сервера.

Хорошо, чтобы удалить все переменные, может быть, самый красивый

 $url = strtok($url, '?'); 

Смотрите здесь о strtok .

Его самый быстрый (см. Ниже), и обрабатывает URL-адреса без «?» должным образом.

Чтобы взять url + querystring и удалить только одну переменную (без использования замены регулярных выражений, которая может быть быстрее в некоторых случаях), вы можете сделать что-то вроде:

 function removeqsvar($url, $varname) { list($urlpart, $qspart) = array_pad(explode('?', $url), 2, ''); parse_str($qspart, $qsvars); @unset($qsvars[$varname]); $newqs = http_build_query($qsvars); return $urlpart . '?' . $newqs; } 

Регулярное выражение для удаления одного var может выглядеть так:

 function removeqsvar($url, $varname) { return preg_replace('/([?&])'.$varname.'=[^&]+(&|$)/','$1',$url); } 

Устанавливает тайминги нескольких разных методов, гарантируя, что синхронизация сбрасывается между циклами.

 <?php $number_of_tests = 40000; $mtime = microtime(); $mtime = explode(" ",$mtime); $mtime = $mtime[1] + $mtime[0]; $starttime = $mtime; for($i = 0; $i < $number_of_tests; $i++){ $str = "http://www.example.com?test=test"; preg_replace('/\\?.*/', '', $str); } $mtime = microtime(); $mtime = explode(" ",$mtime); $mtime = $mtime[1] + $mtime[0]; $endtime = $mtime; $totaltime = ($endtime - $starttime); echo "regexp execution time: ".$totaltime." seconds; "; $mtime = microtime(); $mtime = explode(" ",$mtime); $mtime = $mtime[1] + $mtime[0]; $starttime = $mtime; for($i = 0; $i < $number_of_tests; $i++){ $str = "http://www.example.com?test=test"; $str = explode('?', $str); } $mtime = microtime(); $mtime = explode(" ",$mtime); $mtime = $mtime[1] + $mtime[0]; $endtime = $mtime; $totaltime = ($endtime - $starttime); echo "explode execution time: ".$totaltime." seconds; "; $mtime = microtime(); $mtime = explode(" ",$mtime); $mtime = $mtime[1] + $mtime[0]; $starttime = $mtime; for($i = 0; $i < $number_of_tests; $i++){ $str = "http://www.example.com?test=test"; $qPos = strpos($str, "?"); $url_without_query_string = substr($str, 0, $qPos); } $mtime = microtime(); $mtime = explode(" ",$mtime); $mtime = $mtime[1] + $mtime[0]; $endtime = $mtime; $totaltime = ($endtime - $starttime); echo "strpos execution time: ".$totaltime." seconds; "; $mtime = microtime(); $mtime = explode(" ",$mtime); $mtime = $mtime[1] + $mtime[0]; $starttime = $mtime; for($i = 0; $i < $number_of_tests; $i++){ $str = "http://www.example.com?test=test"; $url_without_query_string = strtok($str, '?'); } $mtime = microtime(); $mtime = explode(" ",$mtime); $mtime = $mtime[1] + $mtime[0]; $endtime = $mtime; $totaltime = ($endtime - $starttime); echo "tok execution time: ".$totaltime." seconds; "; 

шоу

 regexp execution time: 0.14604902267456 seconds; explode execution time: 0.068033933639526 seconds; strpos execution time: 0.064775943756104 seconds; tok execution time: 0.045819044113159 seconds; regexp execution time: 0.1408839225769 seconds; explode execution time: 0.06751012802124 seconds; strpos execution time: 0.064877986907959 seconds; tok execution time: 0.047760963439941 seconds; regexp execution time: 0.14162802696228 seconds; explode execution time: 0.065848112106323 seconds; strpos execution time: 0.064821004867554 seconds; tok execution time: 0.041788101196289 seconds; regexp execution time: 0.14043688774109 seconds; explode execution time: 0.066350221633911 seconds; strpos execution time: 0.066242933273315 seconds; tok execution time: 0.041517972946167 seconds; regexp execution time: 0.14228296279907 seconds; explode execution time: 0.06665301322937 seconds; strpos execution time: 0.063700199127197 seconds; tok execution time: 0.041836977005005 seconds; 

strtok выигрывает и, безусловно, самый маленький код.

Как насчет:

 preg_replace('/\\?.*/', '', $str) 

Вдохновленный комментарием @MitMaro, я написал небольшой ориентир, чтобы проверить скорость решений @Gumbo, @Matt Bridges и @ justin предложение в вопросе:

 function teststrtok($number_of_tests){ for($i = 0; $i < $number_of_tests; $i++){ $str = "http://www.example.com?test=test"; $str = strtok($str,'?'); } } function testexplode($number_of_tests){ for($i = 0; $i < $number_of_tests; $i++){ $str = "http://www.example.com?test=test"; $str = explode('?', $str); } } function testregexp($number_of_tests){ for($i = 0; $i < $number_of_tests; $i++){ $str = "http://www.example.com?test=test"; preg_replace('/\\?.*/', '', $str); } } function teststrpos($number_of_tests){ for($i = 0; $i < $number_of_tests; $i++){ $str = "http://www.example.com?test=test"; $qPos = strpos($str, "?"); $url_without_query_string = substr($str, 0, $qPos); } } $number_of_runs = 10; for($runs = 0; $runs < $number_of_runs; $runs++){ $number_of_tests = 40000; $functions = array("strtok", "explode", "regexp", "strpos"); foreach($functions as $func){ $starttime = microtime(true); call_user_func("test".$func, $number_of_tests); echo $func.": ". sprintf("%0.2f",microtime(true) - $starttime).";"; } echo "<br />"; } 
 strtok: 0,12; взрыв: 0,19; regexp: 0,31; strpos: 0,18;
 strtok: 0,12; взрыв: 0,19; regexp: 0,31; strpos: 0,18;
 strtok: 0,12; взрыв: 0,19; regexp: 0,31; strpos: 0,18;
 strtok: 0,12; взрыв: 0,19; regexp: 0,31; strpos: 0,18;
 strtok: 0,12; взрыв: 0,19; regexp: 0,31; strpos: 0,18;
 strtok: 0,12; взрыв: 0,19; regexp: 0,31; strpos: 0,18;
 strtok: 0,12; взрыв: 0,19; regexp: 0,31; strpos: 0,18;
 strtok: 0,12; взрыв: 0,19; regexp: 0,31; strpos: 0,18;
 strtok: 0,12; взрыв: 0,19; regexp: 0,31; strpos: 0,18;
 strtok: 0,12; взрыв: 0,19; regexp: 0,31; strpos: 0,18;

Результат: strtok @ justin является самым быстрым.

Примечание: проверено на локальной системе Debian Lenny с Apache2 и PHP5.

Если URL, который вы пытаетесь удалить строку запроса, это текущий URL-адрес скрипта PHP, вы можете использовать один из ранее упомянутых методов. Если у вас просто есть строковая переменная с URL-адресом в ней, и вы хотите удалить все из-за «?» ты можешь сделать:

 $pos = strpos($url, "?"); $url = substr($url, 0, $pos); 

Другое решение … Я нахожу эту функцию более элегантной, она также удалит конечный «?» если ключ для удаления является единственным в строке запроса.

 /** * Remove a query string parameter from an URL. * * @param string $url * @param string $varname * * @return string */ function removeQueryStringParameter($url, $varname) { $parsedUrl = parse_url($url); $query = array(); if (isset($parsedUrl['query'])) { parse_str($parsedUrl['query'], $query); unset($query[$varname]); } $path = isset($parsedUrl['path']) ? $parsedUrl['path'] : ''; $query = !empty($query) ? '?'. http_build_query($query) : ''; return $parsedUrl['scheme']. '://'. $parsedUrl['host']. $path. $query; } с /** * Remove a query string parameter from an URL. * * @param string $url * @param string $varname * * @return string */ function removeQueryStringParameter($url, $varname) { $parsedUrl = parse_url($url); $query = array(); if (isset($parsedUrl['query'])) { parse_str($parsedUrl['query'], $query); unset($query[$varname]); } $path = isset($parsedUrl['path']) ? $parsedUrl['path'] : ''; $query = !empty($query) ? '?'. http_build_query($query) : ''; return $parsedUrl['scheme']. '://'. $parsedUrl['host']. $path. $query; } 

тесты:

 $urls = array( 'http://www.example.com?test=test', 'http://www.example.com?bar=foo&test=test2&foo2=dooh', 'http://www.example.com', 'http://www.example.com?foo=bar', 'http://www.example.com/test/no-empty-path/?foo=bar&test=test5', 'https://www.example.com/test/test.test?test=test6', ); foreach ($urls as $url) { echo $url. '<br/>'; echo removeQueryStringParameter($url, 'test'). '<br/><br/>'; } 

Вывод:

 http://www.example.com?test=test http://www.example.com http://www.example.com?bar=foo&test=test2&foo2=dooh http://www.example.com?bar=foo&foo2=dooh http://www.example.com http://www.example.com http://www.example.com?foo=bar http://www.example.com?foo=bar http://www.example.com/test/no-empty-path/?foo=bar&test=test5 http://www.example.com/test/no-empty-path/?foo=bar https://www.example.com/test/test.test?test=test6 https://www.example.com/test/test.test 

»Запустите эти тесты на 3v4l

Вы можете использовать переменные сервера для этого, например $_SERVER['REQUEST_URI'] или даже лучше: $_SERVER['PHP_SELF'] .

Не могли бы вы использовать переменные сервера для этого?

Или эта работа ?:

 unset($_GET['page']); $url = $_SERVER['SCRIPT_NAME'] ."?".http_build_query($_GET); с unset($_GET['page']); $url = $_SERVER['SCRIPT_NAME'] ."?".http_build_query($_GET); 

Просто мысль.

Как насчет функции переписать строку запроса, перейдя через массив $ _GET

! Грубая схема подходящей функции

 function query_string_exclude($exclude, $subject = $_GET, $array_prefix=''){ $query_params = array; foreach($subject as $key=>$var){ if(!in_array($key,$exclude)){ if(is_array($var)){ //recursive call into sub array $query_params[] = query_string_exclude($exclude, $var, $array_prefix.'['.$key.']'); }else{ $query_params[] = (!empty($array_prefix)?$array_prefix.'['.$key.']':$key).'='.$var; } } } return implode('&',$query_params); } 

Что-то вроде этого было бы хорошо держать под рукой для ссылок на страницы и т. Д.

 <a href="?p=3&<?= query_string_exclude(array('p')) ?>" title="Click for page 3">Page 3</a> 
 @list($url) = explode("?", $url, 2); 

basename($_SERVER['REQUEST_URI']) возвращает все после и включая «?»,

В моем коде иногда мне нужны только разделы, поэтому отделите его, чтобы я мог получить значение того, что мне нужно на лету. Не уверен в скорости работы по сравнению с другими методами, но это действительно полезно для меня.

 $urlprotocol = 'http'; if ($_SERVER["HTTPS"] == "on") {$urlprotocol .= "s";} $urlprotocol .= "://"; $urldomain = $_SERVER["SERVER_NAME"]; $urluri = $_SERVER['REQUEST_URI']; $urlvars = basename($urluri); $urlpath = str_replace($urlvars,"",$urluri); $urlfull = $urlprotocol . $urldomain . $urlpath . $urlvars; 

На мой взгляд, лучший способ:

 <? if(isset($_GET['i'])){unset($_GET['i']); header('location:/');} ?> 

Он проверяет, есть ли параметр «i» GET и удаляет его, если есть.