Как избежать URL-адреса для fopen

Похоже, fopen не может открывать файлы с пробелами. Например:

$url = 'http://gatewaypeople.com/images/articles/cntrbutnssttmnts12_main 616x200.jpg'; fopen($url, 'r'); 

возвращает false (помните пространство в URL-адресе), но файл доступен браузерами. Я также пытался убежать от urlencode и rawurlencode без везения. Как правильно избежать пробелов?

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

 $arr = parse_url ( 'http://gatewaypeople.com/images/articles/cntrbutnssttmnts12_main 616x200.jpg' ); $parts = explode ( '/', $arr['path'] ); $fname = $parts[count($parts)-1]; unset($parts[count($parts)-1]); $url = $arr['scheme'] . '://' . $arr['host'] . join('/', $parts) . '/' . urlencode ( $fname ); var_dump( $url ); не $arr = parse_url ( 'http://gatewaypeople.com/images/articles/cntrbutnssttmnts12_main 616x200.jpg' ); $parts = explode ( '/', $arr['path'] ); $fname = $parts[count($parts)-1]; unset($parts[count($parts)-1]); $url = $arr['scheme'] . '://' . $arr['host'] . join('/', $parts) . '/' . urlencode ( $fname ); var_dump( $url ); 

Альтернативный и короткий ответ (спасибо @Dziamid)

 $url = 'http://gatewaypeople.com/images/articles/cntrbutnssttmnts12_main 616x200.jpg'; $parts = pathinfo($url); $url = $parts['dirname'] . '/' . urlencode($parts['basename']); var_dump( $url ); 

ВЫВОД:

 string(76) "http://gatewaypeople.com/images/articles/cntrbutnssttmnts12_main+616x200.jpg" 

rawurlencode – это путь, но не избежать полного URL-адреса. Удалите только имя файла. Итак, вы попадете в http://gatewaypeople.com/images/articles/cntrbutnssttmnts12_main%20616x200.jpg

Все предлагаемые здесь решения являются неправильными, поскольку они не избегают части строки запроса и части базового каталога. Кроме того, они не принимают во внимание детали пользователя, пропуски и фрагменты 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/

Приветствия 🙂

 $url = 'http://gatewaypeople.com/images/articles/cntrbutnssttmnts12_main 616x200.jpg'; fopen(urlencode($url), 'r');