如何在PHP中正确地对字符串进行URL编码?


97

我正在搜索页面,您可以在其中输入搜索查询并将表单提交到search.php?query=your query。什么PHP函数是最好的,我应该使用它对搜索查询进行编码/解码?


2
你有什么问题吗?浏览器和PHP应该已经自动处理了(例如foo bar,输入文本字段,foo+bar在URL中创建)。
Felix Kling

@Felix我将使用以下方式调用搜索脚本file_get_contents
单击Upvote 2011年

Answers:


183

对于URI查询,请使用urlencode/ urldecode; 对于其他任何事情,请使用rawurlencode/ rawurldecode

urlencode和之间的区别rawurlencode


application / x-www-form-urlencoded只是Percent-Encoding的一个特殊变体,仅用于对HTML表单数据进行编码。
Gumbo

1
@Click Upvote:无法以这种方式进行比较。的应用程序/ x-WWW窗体-urlencoded格式所述百分比编码不同之处在于空间与编码格式+代替%20。除此之外,application / x-www-form-urlencoded用于对表单数据进行编码,而Percent-Encoding具有更通用的用法。
Gumbo

12
rawurlencode()与javascript encodeURI()函数兼容
Clive Paterson

这条规则是否总是经验性的?我的意思是,当我需要编码查询字符串时,我总是使用urldecode。然后,关于URI路径(例如/a/path with spaces/)和URI片段(例如#fragment)。我应该一直使用rawurldecode这两个吗?
tonix

一个好的经验法则是,对于路径(例如/ my%20folder /),请使用rawurlencode; 但对于POST和GET字段,请使用urlencode(Like /?folder = my + folder)`
Soroush Falahati

22

狡猾的urlencode()urldecode()

但是,您不需要使用urldecode()出现在$_POST和中的变量$_GET


4
您能否详细说明为什么urldecode()不应与$ _POST一起使用。因为我从很久以前就一直这样做,没有任何问题。
sid

我是否需要编码"name=b&age=c&location=d"通过AJAX发送到PHP文件的基本参数(例如)?
oldboy

9

这是我的用例,它需要大量的编码。也许您认为它是人为的,但我们将其用于生产。巧合的是,这涵盖了每种编码类型,因此我将其发布为教程。

用例说明

有人刚在我们的网站上购买了预付的礼品卡(“令牌”)。令牌具有相应的URL来兑换它们。该客户希望通过电子邮件将URL发送给其他人。我们的网页包含一个mailto链接,使他们可以执行此操作。

PHP代码

// The order system generates some opaque token
$token = 'w%a&!e#"^2(^@azW';

// Here is a URL to redeem that token
$redeemUrl = 'https://httpbin.org/get?token=' . urlencode($token);

// Actual contents we want for the email
$subject = 'I just bought this for you';
$body = 'Please enter your shipping details here: ' . $redeemUrl;

// A URI for the email as prescribed
$mailToUri = 'mailto:?subject=' . rawurlencode($subject) . '&body=' . rawurlencode($body);

// Print an HTML element with that mailto link
echo '<a href="' . htmlspecialchars($mailToUri) . '">Email your friend</a>';

注意:以上假设您正在输出到text/html文档。如果text/json仅使用输出媒体类型,$retval['url'] = $mailToUri;因为输出编码由处理json_encode()

测试用例

  1. 在PHP测试站点上运行代码(在这里我应该提到一个规范的代码吗?
  2. 点击链接
  3. 发送邮件
  4. 取得电子邮件
  5. 点击该链接

您应该看到:

"args": {
  "token": "w%a&!e#\"^2(^@azW"
}, 

当然,这是$token上面的JSON表示形式。


等效地,并且在语义上较少(因为mailto:不是HTTP),可以使用$mailToUri 'mailto:?' . http_build_query(['subject'=>$subject, 'body'=>$body], null, '&', PHP_QUERY_RFC3986);
威廉·恩崔肯


0

根据要执行的RFC标准编码类型,或者如果需要自定义编码,可能要创建自己的类。

/**
 * UrlEncoder make it easy to encode your URL
 */
class UrlEncoder{
    public const STANDARD_RFC1738 = 1;
    public const STANDARD_RFC3986 = 2;
    public const STANDARD_CUSTOM_RFC3986_ISH = 3;
    // add more here

    static function encode($string, $rfc){
        switch ($rfc) {
            case self::STANDARD_RFC1738:
                return  urlencode($string);
                break;
            case self::STANDARD_RFC3986:
                return rawurlencode($string);
                break;
            case self::STANDARD_CUSTOM_RFC3986_ISH:
                // Add your custom encoding
                $entities = ['%21', '%2A', '%27', '%28', '%29', '%3B', '%3A', '%40', '%26', '%3D', '%2B', '%24', '%2C', '%2F', '%3F', '%25', '%23', '%5B', '%5D'];
                $replacements = ['!', '*', "'", "(", ")", ";", ":", "@", "&", "=", "+", "$", ",", "/", "?", "%", "#", "[", "]"];
                return str_replace($entities, $replacements, urlencode($string));
                break;
            default:
                throw new Exception("Invalid RFC encoder - See class const for reference");
                break;
        }
    }
}

使用示例:

$dataString = "https://www.google.pl/search?q=PHP is **great**!&id=123&css=#kolo&email=me@liszka.com)";

$dataStringUrlEncodedRFC1738 = UrlEncoder::encode($dataString, UrlEncoder::STANDARD_RFC1738);
$dataStringUrlEncodedRFC3986 = UrlEncoder::encode($dataString, UrlEncoder::STANDARD_RFC3986);
$dataStringUrlEncodedCutom = UrlEncoder::encode($dataString, UrlEncoder::STANDARD_CUSTOM_RFC3986_ISH);

将输出:

string(126) "https%3A%2F%2Fwww.google.pl%2Fsearch%3Fq%3DPHP+is+%2A%2Agreat%2A%2A%21%26id%3D123%26css%3D%23kolo%26email%3Dme%40liszka.com%29"
string(130) "https%3A%2F%2Fwww.google.pl%2Fsearch%3Fq%3DPHP%20is%20%2A%2Agreat%2A%2A%21%26id%3D123%26css%3D%23kolo%26email%3Dme%40liszka.com%29"
string(86)  "https://www.google.pl/search?q=PHP+is+**great**!&id=123&css=#kolo&email=me@liszka.com)"

*了解有关RFC标准的更多信息:https : //datatracker.ietf.org/doc/rfc3986/ 以及urlencode和rawurlencode?

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.