PHP中与JavaScript的encodeURIcomponent相当的是什么?

106

在PHP中,与JavaScript的encodeURIcomponent函数相对应的函数是什么?


1
一个不错的比较:http://devpro.it/examples/php_js_escaping.php - philfreo
5个回答

165

尝试使用rawurlencode。或者更加精确地说:

function encodeURIComponent($str) {
    $revert = array('%21'=>'!', '%2A'=>'*', '%27'=>"'", '%28'=>'(', '%29'=>')');
    return strtr(rawurlencode($str), $revert);
}

这个函数的工作方式与encodeURIComponent的定义完全相同:

encodeURIComponent转义除以下字符外的所有字符:字母、十进制数字、-_.!~*'()


谢谢!我本以为可以不用函数来完成它,但好吧。 - Gal
1
@Gal:如果你需要一个完全相同的输出,你才需要那个函数。 - Gumbo
@Gumbo 在 Firefox 扩展程序中,我注意到他们将图像传递给 JavaScript 的 encodeURIComponent。请参见 https://addons.mozilla.org/nl/firefox/files/browse/126380/file/chrome/content/googlereverseimagesearch.js#top,第 137 行。我该如何在 PHP 中实现相同的功能? - user410932
我不相信 rawurlencode 会对逗号进行编码(这对于 URI 组件是必须的)。 - Chris Rae
它们很接近,但是rawurlencodeencodeURIComponent并不完全相同。例如,前者会对单引号进行编码,而后者则不会。 - wunch
在 JavaScript 中,encodeURIComponent(str) 将 š 转换为 %C5%A1。 而在 PHP 中,您的函数 encodeURIComponent() 将 š 转换为 %26scaron%3B。 - Hassan Amir Khan

8
你是否尝试使用 urlencode 进行转码?

3
好的,问题在于它不完全像encodeURI,它转换了每个字符,甚至包括^符号。我希望有一种方式可以完全相同地运行,而不需要我的干预^^。 - Gal

3

function encodeURIComponent($string) {
   $result = "";
   for ($i = 0; $i < strlen($string); $i++) {
      $result .= encodeURIComponentbycharacter(urlencode($string[$i]));
   }
   return $result;
}

以上是一个用于将字符串进行编码的函数。该函数采用了循环遍历字符串中的每个字符,并通过调用encodeURIComponentbycharacter和urlencode函数来对字符进行编码。最终,该函数返回编码后的结果。

function encodeURIComponentbycharacter($char) { 如果($char == "+") { 返回 "%20"; } 如果($char == "%21") { 返回 "!"; } 如果($char == "%27") { 返回 '"'; } 如果($char == "%28") { 返回 "("; } 如果($char == "%29") { 返回 ")"; } 如果($char == "%2A") { 返回 "*"; } 如果($char == "%7E") { 返回 "~"; } 如果($char == "%80") { 返回 "%E2%82%AC"; } 如果($char == "%81") { 返回 "%C2%81"; } 如果($char == "%82") { 返回 "%E2%80%9A"; } 如果($char == "%83") { 返回 "%C6%92"; } 如果($char == "%84") { 返回 "%E2%80%9E"; } 如果($char == "%85") { 返回 "%E2%80%A6"; } 如果($char == "%86") { 返回 "%E2%80%A0"; } 如果($char == "%87") { 返回 "%E2%80%A1"; } 如果($char == "%88") { 返回 "%CB%86"; } 如果($char == "%89") { 返回 "%E2%80%B0"; } 如果($char == "%8A") { 返回 "%C5%A0"; } 如果($char == "%8B") { 返回 "%E2%80%B9"; } 如果($char == "%8C") { 返回 "%C5%92"; } 如果($char == "%8D") { 返回 "%C2%8D"; } 如果($char == "%8E") { 返回 "%C5%BD"; } 如果($char == "%8F") { 返回 "%C2%8F"; } 如果($char == "%90") { 返回 "%C2%90"; } 如果($char == "%91") { 返回 "%E2%80%98"; } 如果($char == "%92") { 返回 "%E2%80%99"; } 如果($char == "%93") { 返回 "%E2%80%9C"; } 如果($char == "%94") { 返回 "%E2%80%9D"; } 如果($char == "%95") { 返回 "%E2%80%A2"; } 如果($char == "%96") { 返回 "%E2%80%93"; } 如果($char == "%97") { 返回 "%E2%80%94"; } 如果($char == "%98") { 返回 "%CB%9C"; } 如果($char == "%99") { 返回 "%E2%84%A2"; } 如果($char == "%9A") { 返回 "%C5%A1"; } 如果($char == "%9B") { 返回 "%E2%80%BA"; } 如果($char == "%9C") { 返回 "%C5%93"; } 如果($char == "%9D") { 返回 "%C2%9D"; } 如果($char == "%9E") { 返回 "%C5%BE"; } 如果($char == "%9F") { 返回 "%C5%B8"; } 如果($char == "%A0") { 返回 "%C2%A0"; } 如果($char == "%A1") { 返回 "%C2%A1"; } 如果($char == "%A2") { 返回 "%C2%A2"; } 如果($char == "%A3") { 返回 "%C2%A3"; } 如果($char == "%A4") { 返回 "%C2%A4"; } 如果($char == "%A5") { 返回 "%C2%A5"; } 如果($char == "%A6") { 返回 "%C2%A6"; } 如果($char == "%A7") { 返回 "%C2%A7"; } 如果($char == "%A8") { 返回 "%C2%A8"; } 如果($char == "%A9") { 返回 "%C2%A9"; } 如果($char == "%AA") { 返回 "%C2%AA"; } 如果($char == "%AB") { 返回 "%C2%AB"; } 如果($char == "%AC") { 返回 "%C2%AC"; } 如果($char == "%AD") { 返回 "%C2%AD"; } 如果($char == "%AE") { 返回 "%C2%AE"; } 如果($char == "%AF") { 返回 "%C2%AF"; } 如果($char == "%B0") { 返回 "%C2%B0"; }


这就是 switch 语句派上用场的地方。 - Yada
3
答案的逻辑对我来说是有争议的,无论如何,在这种情况下,IF或SWITCH链都表现不佳。这是一个典型的情况,其中索引数组是最佳解决方案,查找值是关键。 - yodabar

1

这段代码怎么样?
我对每个层级进行了编码。
实际上它与encodeURI不同,但你可以对主机名和“/”进行编码。

function encodeURI($url) {
    if(__empty($url))return $url; 

    $res = preg_match('/.*:\/\/(.*?)\//',$url,$matches);
    if($res){

        // except host name
        $url_tmp = str_replace($matches[0],"",$url);

        // except query parameter
        $url_tmp_arr = explode("?",$url_tmp);

        // encode each tier
        $url_tear = explode("/", $url_tmp_arr[0]);
        foreach ($url_tear as $key => $tear){
            $url_tear[$key] = rawurlencode($tear);
        }

        $ret_url = $matches[0].implode('/',$url_tear);

        // encode query parameter
        if(count($url_tmp_arr) >= 2){
            $ret_url .= "?".$this->encodeURISub($url_tmp_arr[1]);
        }
        return $ret_url;
    }else{
        return $this->encodeURISub($url);
    }

}

/**
 * https://dev59.com/9W445IYBdhLWcg3wTIjm#6059053
 */
function encodeURISub($url) {
    // http://php.net/manual/en/function.rawurlencode.php
    // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/encodeURI
    $unescaped = array(
    '%2D'=>'-','%5F'=>'_','%2E'=>'.','%21'=>'!', '%7E'=>'~',
    '%2A'=>'*', '%27'=>"'", '%28'=>'(', '%29'=>')'
            );
    $reserved = array(
            '%3B'=>';','%2C'=>',','%2F'=>'/','%3F'=>'?','%3A'=>':',
            '%40'=>'@','%26'=>'&','%3D'=>'=','%24'=>'$'
    );
    $score = array(
            '%23'=>'#'
    );
    return strtr(rawurlencode($url), array_merge($reserved,$unescaped,$score));

}

-2

http_build_query


1
这个回答如何解决问题? - indextwo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接