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?
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"
rawurlencode
is 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
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 :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With