urlencode只有URL的目录和文件名
我需要使用PHP编码URL的目录路径和文件名。urlencode只有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。
有没有比这更优雅的解决方案?或者,这基本上是要走的路?
@deceze肯定让我去沿着正确的道路走,所以赶快回答他的答案。但这里是什么工作:
$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
而不是+
。将空格编码为+
适用于查询字符串,但对于路径不太适合。这对于需要编码的用户名/密码的URL不起作用。对于我的用例,我不认为我在乎这些,所以我并不担心。但是,如果你的用例在这方面有所不同,那么你需要注意这一点。
对,我忘了将完整的URL重新拼回去。我想我们可以改变正则表达式来做非捕捉后视,所以它只提取和修改路径。无论如何。 :) – deceze
正如你所说,这些方针的东西应该这样做:
$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);
(正则表达式没有完全虽然测试)
我觉得这个功能确定:
function newUrlEncode ($url) {
return str_replace(array('%3A', '%2F'), '/', urlencode($url));
}
这适用于问题中的示例,但它不健壮。例如,如果在URL中指定端口,它将返回错误的结果。 – Trott
简单多了:
$encoded = implode("/", array_map("rawurlencode", explode("/", $path)));
请解释您的答案,因为这是一个老问题,建议您告诉我们您的答案与已提供的答案不同。谢谢。 –
这个答案是不正确的。它将编码遵循该方案的冒号。给定输入'http://example.com/file name',它会生成'http%3A // example.com/file%20name'。正确的结果是'http:// example.com/file%20name'。 – Trott
function encode_uri($url){
$exp = "{[^0-9a-z_.!~*'();,/?:@&=+$#%\[\]-]}i";
return preg_replace_callback($exp, function($m){
return sprintf('%%%02X',ord($m[0]));
}, $url);
}
这似乎是最可靠的解决方案给我。 – Herbert
每个文档:urlencode用于URL的查询部分。 rawurlencode的路径,但一定要排除斜杠。 –