Похоже, 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');