Как избежать URL для FOPEN - PullRequest
       7

Как избежать URL для FOPEN

4 голосов
/ 10 января 2012

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

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

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

Ответы [ 4 ]

4 голосов
/ 10 января 2012

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

4 голосов
/ 10 января 2012

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

$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"
1 голос
/ 06 марта 2013

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

0 голосов
/ 10 января 2012
$url = 'http://gatewaypeople.com/images/articles/cntrbutnssttmnts12_main 616x200.jpg';
fopen(urlencode($url), 'r');
...