PHP: как добавить конечную косую черту в абсолютный URL

У меня есть список абсолютных URL-адресов. Мне нужно убедиться, что все они имеют косые черты, если это применимо. Так:

  • http://www.domain.com/ <- не требуется конечная косая черта
  • http://www.domain.com <- требуется конечная косая черта
  • http://www.domain.com/index.php <- не требуется конечная косая черта
  • http://www.domain.com/?message=hello <- не требуется конечная косая черта

Я предполагаю, что мне нужно использовать регулярное выражение, но сопоставление URL-адресов – боль. Надеюсь на более легкое решение. Идеи?

Solutions Collecting From Web of "PHP: как добавить конечную косую черту в абсолютный URL"

Вместо этого с помощью regex вы можете использовать parse_url() для этого. Например:

 $url = parse_url("http://www.example.com/ab/abc.html?a=b#xyz"); if(!isset($url['path'])) $url['path'] = '/'; $surl = $url['scheme']."://".$url['host'].$url['path'].'?'.$url['query'].'#'.$url['fragment']; echo $surl; 

Для этой очень специфической проблемы вообще не может быть использование регулярного выражения. Если ваш список длинный (несколько тысяч URL-адресов) и время вызывает какое-либо беспокойство, вы можете выбрать ручной код этого очень простого манипулирования.

Это сделает то же самое:

 $str .= (substr($str, -1) == '/' ? '' : '/'); 

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

Это, конечно, не будет проверять, что строка действительно хорошо сформированный URL (например, регулярное выражение zerkms), но вы уже знаете, что ваши строки являются URL-адресами, так что это немного избыточно.

Хотя, если ваш список – это что-то вроде 10 или 20 URL-адресов, забудьте об этом сообщении. Используйте регулярное выражение, разница будет равна нулю.

 $url = 'http://www.domain.com'; $need_to_add_trailing_slash = preg_match('~^https?://[^/]+$~', $url); 

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

 if (!preg_match("/.*\/$/", $url)) { $url = "$url" . "/"; } 

Это может быть не самое элегантное решение, но оно работает как шарм. Сначала мы получаем полный URL-адрес, а затем проверяем, имеет ли он конечную косую черту. Если нет, проверьте, нет ли строки запроса, это не фактический файл и не является фактическим каталогом. Если URL-адрес соответствует всем этим условиям, мы делаем 301 переадресацию с добавлением косой черты.

Если вы не знакомы с заголовками PHP … обратите внимание, что перед этим кодом не может быть никакого вывода – даже пробела.

 $url = $_SERVER['REQUEST_URI']; $lastchar = substr( $url, -1 ); if ( $lastchar != '/' ): if ( !$_SERVER['QUERY_STRING'] and !is_file( $_SERVER['DOCUMENT_ROOT'].$url ) and !is_dir( $_SERVER['DOCUMENT_ROOT'].$url ) ): header("HTTP/1.1 301 Moved Permanently"); header( "Location: $url/" ); endif; endif;