我需要使用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()需要像路径一样需要它的部分.然后,我会使用重新组合URL http_build_url().
有比这更优雅的解决方案吗?或者这基本上是要走的路?
Tro*_*ott 17
@deceze绝对让我走上了正确的道路,所以请回答他的回答.但这正是有效的:
$encoded_url = preg_replace_callback('#://([^/]+)/([^?]+)#', function ($match) {
return '://' . $match[1] . '/' . join('/', array_map('rawurlencode', explode('/', $match[2])));
}, $unencoded_url);
Run Code Online (Sandbox Code Playgroud)
有几点需要注意:
http_build_url需要PECL安装,所以如果你要将代码分发给其他人(就像我在这种情况下),你可能想要避免它并坚持使用reg exp解析,就像我在这里做的那样(从@ deceze的答案中大量窃取 - 再次,去吧upvote那件事).
urlencode()不是要走的路!您需要rawurlencode()路径以便空间被编码为%20和不被编码+.将空格编码+为查询字符串,但对路径不太热.
这对于需要编码的用户名/密码的URL不起作用.对于我的用例,我不认为我关心那些,所以我并不担心.但是,如果您的用例在这方面有所不同,那么您需要注意这一点.
dec*_*eze 15
如你所说,沿着这些方向应该做的事情:
$parts = parse_url($url);
if (!empty($parts['path'])) {
$parts['path'] = join('/', array_map('rawurlencode', explode('/', $parts['path'])));
}
$url = http_build_url($parts);
Run Code Online (Sandbox Code Playgroud)
或者可能:
$url = preg_replace_callback('#https?://.+/([^?]+)#', function ($match) {
return join('/', array_map('rawurlencode', explode('/', $match[1])));
}, $url);
Run Code Online (Sandbox Code Playgroud)
(虽然没有完全测试正则表达)