urlencode only the directory and file names of a URL

不想你离开。 提交于 2019-12-05 16:41:41

问题


I need to URL encode just the directory path and file name of a URL using PHP.

So I want to encode something like http://example.com/file name and have it result in http://example.com/file%20name.

Of course, if I do urlencode('http://example.com/file name'); then I end up with http%3A%2F%2Fexample.com%2Ffile+name.

The obvious (to me, anyway) solution is to use parse_url() to split the URL into scheme, host, etc. and then just urlencode() the parts that need it like the path. Then, I would reassemble the URL using http_build_url().

Is there a more elegant solution than that? Or is that basically the way to go?


回答1:


@deceze definitely got me going down the right path, so go upvote his answer. But here is exactly what worked:

    $encoded_url = preg_replace_callback('#://([^/]+)/([^?]+)#', function ($match) {
                return '://' . $match[1] . '/' . join('/', array_map('rawurlencode', explode('/', $match[2])));
            }, $unencoded_url);

There are a few things to note:

  • http_build_url requires a PECL install so if you are distributing your code to others (as I am in this case) you might want to avoid it and stick with reg exp parsing like I did here (stealing heavily from @deceze's answer--again, go upvote that thing).

  • urlencode() is not the way to go! You need rawurlencode() for the path so that spaces get encoded as %20 and not +. Encoding spaces as + is fine for query strings, but not so hot for paths.

  • This won't work for URLs that need a username/password encoded. For my use case, I don't think I care about those, so I'm not worried. But if your use case is different in that regard, you'll need to take care of that.




回答2:


As you say, something along these lines should do it:

$parts = parse_url($url);
if (!empty($parts['path'])) {
    $parts['path'] = join('/', array_map('rawurlencode', explode('/', $parts['path'])));
}
$url = http_build_url($parts);

Or possibly:

$url = preg_replace_callback('#https?://.+/([^?]+)#', function ($match) {
           return join('/', array_map('rawurlencode', explode('/', $match[1])));
       }, $url);

(Regex not fully tested though)




回答3:


function encode_uri($url){
    $exp = "{[^0-9a-z_.!~*'();,/?:@&=+$#%\[\]-]}i";
    return preg_replace_callback($exp, function($m){
        return sprintf('%%%02X',ord($m[0]));
    }, $url);
}



回答4:


Much simpler:

$encoded = implode("/", array_map("rawurlencode", explode("/", $path)));



回答5:


I think this function ok:

function newUrlEncode ($url) {
    return str_replace(array('%3A', '%2F'), '/', urlencode($url));
}


来源:https://stackoverflow.com/questions/7973790/urlencode-only-the-directory-and-file-names-of-a-url

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!