Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to escape url for fopen

Tags:

php

fopen

It looks like fopen can't open files with spaces. For example:

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

returns false (mind the space in the url), but file is accessible by browsers. I've also tried to escape the url by urlencode and rawurlencode with no luck. How to properly escape the spaces?

like image 225
Dziamid Avatar asked Jan 10 '12 09:01

Dziamid


3 Answers

You can use this code:

$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 );

Alternative & Shorter Answer (Thanks to @Dziamid)

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

OUTPUT:

string(76) "http://gatewaypeople.com/images/articles/cntrbutnssttmnts12_main+616x200.jpg"
like image 75
anubhava Avatar answered Sep 22 '22 18:09

anubhava


rawurlencodeis the way to go, but no not escape the full URL. Only escape the filename. So you will end up in http://gatewaypeople.com/images/articles/cntrbutnssttmnts12_main%20616x200.jpg

like image 34
fab Avatar answered Sep 22 '22 18:09

fab


All solutions proposed here are wrong because they don't escape the query string part and the base directory part. Additionally they don't take in consideration user, pass and fragment url parts.

To correctly escape a valid URL you have to separately escape the path parts and the query parts. So the solution is to extract the url parts, escape each part and rebuild the url.

Here is a simple code snippet:

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;
}

Usage would simply be:

$encodedUrl = safeUrlEncode( $originalUrl );

Side note In my code snippet i'm making use of http://php.net/manual/it/function.http-build-url.php which is available under PECL extension. If you don't have PECL extension on your server you can simply include the pure PHP implementation: http://fuelforthefire.ca/free/php/http_build_url/

Cheers :)

like image 45
Stefano Pochet Avatar answered Sep 22 '22 18:09

Stefano Pochet