2012-01-10 54 views
4

看起來fopen無法打開帶空格的文件。 例如:如何爲fopen轉義url

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

假(介意的URL的空間),但文件是通過瀏覽器訪問。 我也試圖逃過網址urlencoderawurlencode沒有運氣。如何正確地逃避空間?

+0

URL中不能有空格的擺在首位。 – Quentin 2012-01-10 12:33:43

+0

請參閱我的答案,我認爲它可以幫助 – 2013-05-02 22:03:41

回答

3

結束了,您可以使用此代碼:

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

OUTPUT:

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

剛好如何:'$ parts = pathinfo($ url); $ url = $ parts ['dirname']。 '/'。 rawurlencode($ parts ['basename'])'? – Dziamid 2012-01-10 10:15:17

+0

@Dziamid:謝謝,那肯定會起作用。還更新了我的答案。 – anubhava 2012-01-10 12:04:50

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

rawurlencode是要走的路,但不能逃避完整的URL。只能轉義文件名。所以,你會在http://gatewaypeople.com/images/articles/cntrbutnssttmnts12_main%20616x200.jpg

+0

我想我應該用'/'拆分路徑,rawurlencode部分並將它們分解回來? – Dziamid 2012-01-10 10:03:47

+1

基本上,是的。但是您可以使用[parse_url](http://de3.php.net/manual/en/function.parse-url.php)進行分析。並且沒有必要對主機,協議等進行編碼。只有'path','query'和'fragment'(如果適用) – fab 2012-01-10 10:08:39

1

此處提出的所有解決方案都是錯誤的,因爲它們不會轉義查詢字符串部分和基本目錄部分。此外,他們不考慮用戶,傳遞和片段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/

乾杯:)

+0

@anubhava您的解決方案不會轉義查詢字符串部分和基本目錄部分。此外,他們不考慮用戶,傳遞和片段url部分。 – 2013-03-06 12:46:56