如何在PHP中仅对URL的非ASCII符号进行URL编码,但是保留的符号是否未编码?

Aur*_*mas 12 php urlencode utf-8

我有一个看起来像这样的URL(注意""符号):

http://tinklarastis.omnitel.lt/kokius-aptarnavimo-kanalus-klientui-siulo-„omnitel“-1494

我从SimplePie解析器接收它,如果这很重要.现在,如果您尝试在浏览器中访问此特定URL并从地址栏复制它,您将获得一个具有非ASCII符号百分比编码的URL :

http://tinklarastis.omnitel.lt/kokius-aptarnavimo-kanalus-klientui-siulo-%E2%80%9Eomnitel%E2%80%9C-1494

我试图了解如何在PHP中模仿相同的转换.我不能简单地使用urlencode()urlrawencode()编码非ASCII符号保留符号,而在我的情况下,保留符号(/?&等)应保持原样.

到目前为止,我只看到了将URL拆分为保留符号之间然后使用的解决方案urlencode(),但这对我来说感觉很乱,我希望有更优雅的解决方案.我已经试过的各种变化iconv(),mb_convert_encoding(),但没有成功呢.

小智 11

我有一个简单的单行程序,我用它来使用preg_match_callback对非ASCII字符进行就地编码:

preg_replace_callback('/[^\x20-\x7f]/', function($match) {
    return urlencode($match[0]);
}, $url);
Run Code Online (Sandbox Code Playgroud)

但是据我所知,匿名函数仅在PHP 5.3+中受支持.

  • **这应该是公认的答案。** 它处理 URL 中任何位置的非 ASCII 字符(路径 **和** 查询字符串),并且不需要执行诸如 OP 中的“避免双重编码”之类的检查回答。 (3认同)

Aur*_*mas 9

经过一番研究后,我得出结论,在PHP中没有办法做得很好(但是,像python/perl这样的其他语言似乎确实具有这个用例的功能).这是我提出的功能(确保URL的路径片段的编码):

function url_path_encode($url) {
    $path = parse_url($url, PHP_URL_PATH);
    if (strpos($path,'%') !== false) return $url; //avoid double encoding
    else {
        $encoded_path = array_map('urlencode', explode('/', $path));
        return str_replace($path, implode('/', $encoded_path), $url);
    }   
}
Run Code Online (Sandbox Code Playgroud)