我有一个看起来像这样的网址(注意“”符号):
http://tinklarastis.omnitel.lt/kokius-aptarnavimo-kanalus-klientui-siulo-„omnitel“-1494
我从SimplePie解析器接收它,如果这很重要的话。现在,如果您尝试在浏览器中访问此特定URL并从地址栏复制它,您将获得一个包含非ASCII符号的网址percent encoded:
http://tinklarastis.omnitel.lt/kokius-aptarnavimo-kanalus-klientui-siulo-%E2%80%9Eomnitel%E2%80%9C-1494
我试图理解如何在PHP中模仿相同的转换。我不能简单地使用urlencode()
或urlrawencode()
来编码非ASCII符号和保留符号,而在我的情况下,保留符号(/?&等)应该保持原样。
到目前为止,我只看到solutions涉及将URL拆分为保留符号之间的部分,然后使用urlencode()
,但这对我来说感觉很乱,我希望有一个更优雅的解决方案。我尝试了iconv()
,mb_convert_encoding()
的各种变体,但还没有成功。
答案 0 :(得分: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);
}
}
答案 1 :(得分:9)
我有一个简单的单行程序,我用它来使用preg_match_callback对非ASCII字符进行就地编码:
preg_replace_callback('/[^\x20-\x7f]/', function($match) {
return urlencode($match[0]);
}, $url);
请注意,只有PHP 5.3 +支持匿名函数。
答案 2 :(得分:2)
我认为这会做你想要的。
<?php
$string = 'http://tinklarastis.omnitel.lt/kokius-aptarnavimo-kanalus-klientui-siulo-„omnitel“-1494/?foo=bar&fizz=buzz';
var_dump(filter_var($string, FILTER_SANITIZE_STRING, FILTER_FLAG_ENCODE_HIGH));
这会让你:
$ php test.php
string(140) "http://tinklarastis.omnitel.lt/kokius-aptarnavimo-kanalus-klientui-siulo-„omnitel“-1494/?foo=bar&fizz=buzz"
答案 3 :(得分:2)
此功能可能有所帮助:
function sanitizeUrl($url)
{
$chars = '$-_.+!*\'(),{}|\\^~[]`<>#%";/?:@&=';
$pattern = '~[^a-z0-9' . preg_quote($chars, '~') . ']+~iu';
$callback = create_function('$matches', 'return urlencode($matches[0]);');
return preg_replace_callback($pattern, $callback, $url);
}
答案 4 :(得分:0)
function cyrillicaToUrlencode($text){
return $line = preg_replace_callback('/([а-яё])/ui',
function ($matches) {
return urlencode($matches[0]);
},
$text);
}
echo cyrillicaToUrlencode("https://test.com/Москваёtext1Воронежtext2Москваёtext3yМоскваё___-Москваё");