我需要使用PHP对URL的目录路径和文件名进行URL编码。
所以我想对http://example.com/file name
之类的内容进行编码,并将其生成http://example.com/file%20name
。
当然,如果我urlencode('http://example.com/file name');
,那么我最终会使用http%3A%2F%2Fexample.com%2Ffile+name
。
显而易见的(对我而言)解决方案是使用parse_url()
将URL拆分为方案,主机等,然后只需urlencode()
需要它的部分,如路径。然后,我将使用http_build_url()
重新组合URL。
有比这更优雅的解决方案吗?或者这基本上是要走的路?
答案 0 :(得分:17)
$encoded_url = preg_replace_callback('#://([^/]+)/([^?]+)#', function ($match) {
return '://' . $match[1] . '/' . join('/', array_map('rawurlencode', explode('/', $match[2])));
}, $unencoded_url);
有几点需要注意:
http_build_url需要PECL安装,所以如果你要将代码分发给其他人(就像我在这种情况下那样)你可能想要避免它并坚持使用reg exp解析就像我在这里做的那样(从@ deceze的大量窃取回答 - 再说一遍,那就是投票。
urlencode()
不是要走的路!您需要rawurlencode()
作为路径,以便将空格编码为%20
而不是+
。将空格编码为+
对于查询字符串来说很好,但对路径来说不是那么热。
这不适用于需要编码的用户名/密码的网址。对于我的用例,我不认为我关心那些,所以我并不担心。但是,如果您的用例在这方面有所不同,那么您需要注意这一点。
答案 1 :(得分:15)
正如你所说,沿着这些方向应该做的事情:
$parts = parse_url($url);
if (!empty($parts['path'])) {
$parts['path'] = join('/', array_map('rawurlencode', explode('/', $parts['path'])));
}
$url = http_build_url($parts);
或者可能:
$url = preg_replace_callback('#https?://.+/([^?]+)#', function ($match) {
return join('/', array_map('rawurlencode', explode('/', $match[1])));
}, $url);
(虽然没有完全测试正则表达式)
答案 2 :(得分:1)
function encode_uri($url){
$exp = "{[^0-9a-z_.!~*'();,/?:@&=+$#%\[\]-]}i";
return preg_replace_callback($exp, function($m){
return sprintf('%%%02X',ord($m[0]));
}, $url);
}
答案 3 :(得分:0)
更简单:
$encoded = implode("/", array_map("rawurlencode", explode("/", $path)));
答案 4 :(得分:-1)
我觉得这个功能还可以:
function newUrlEncode ($url) {
return str_replace(array('%3A', '%2F'), '/', urlencode($url));
}