Все предлагаемые здесь решения неверны, поскольку они не экранируют часть строки запроса и часть основного каталога.Кроме того, они не учитывают пользовательские, передаваемые и фрагментированные части URL.
Чтобы правильно экранировать действительный URL-адрес, необходимо отдельно экранировать части пути и части запроса.Таким образом, решение состоит в том, чтобы извлечь части url, экранировать каждую часть и перестроить url.
Вот простой фрагмент кода:
function safeUrlEncode( $url ) {
$urlParts = parse_url($url);
$urlParts['path'] = safeUrlEncodePath( $urlParts['path'] );
$urlParts['query'] = safeUrlEncodeQuery( $urlParts['query'] );
return http_build_url($urlParts);
}
function safeUrlEncodePath( $path ) {
if( strlen( $path ) == 0 || strpos($path, "/") === false ){
return "";
}
$pathParts = explode( "/" , $path );
return implode( "/", $pathParts );
}
function safeUrlEncodeQuery( $query ) {
$queryParts = array();
parse_str($query, $queryParts);
$queryParts = urlEncodeArrayElementsRecursively( $queryParts );
return http_build_query( $queryParts );
}
function urlEncodeArrayElementsRecursively( $array ){
if( ! is_array( $array ) ) {
return urlencode( $array );
} else {
foreach( $array as $arrayKey => $arrayValue ){
$array[ $arrayKey ] = urlEncodeArrayElementsRecursively( $arrayValue );
}
}
return $array;
}
Использование будет просто:
$encodedUrl = safeUrlEncode( $originalUrl );
Примечание В моем фрагменте кода я использую http://php.net/manual/it/function.http-build-url.php, который доступен под расширением PECL.Если у вас нет расширения PECL на вашем сервере, вы можете просто включить чистую реализацию PHP: http://fuelforthefire.ca/free/php/http_build_url/
Cheers:)