PHPで文字列を適切にURLエンコードする方法は?


97

検索クエリを入力してフォームがに送信される検索ページを作成していsearch.php?query=your queryます。どのPHP関数が最適で、検索クエリのエンコード/デコードに使用する必要がありますか?


2
問題はありますか?ブラウザとPHPはこれを自動的に処理する必要があります(たとえばfoo bar、テキストフィールドにfoo+bar入力し、URL に作成します)。
Felix Kling、2011年

@Felix私は使用してサーチャースクリプトを呼び出すつもりですfile_get_contents
Upvoteをクリックします

回答:


183

URIクエリにはurlencode/を使用しurldecodeます。それ以外の場合はrawurlencode/を使用しますrawurldecode

違いurlencodeとは、rawurlencodeということです


application / x-www-form-urlencodedは、Percent-Encodingの特別なバリアントであり、HTMLフォームデータのエンコードにのみ適用されます。
ガンボ2011年

1
@Click Upvote:それらはそのように比較することはできません。アプリケーション/ x-www-form-urlencodedでフォーマットは、あるパーセントエンコーディング空間を用いて符号化されることを除いフォーマット+の代わりに%20。さらに、application / x-www-form-urlencodedはフォームデータのエンコードに使用され、Percent-Encodingはより一般的な使用法です。
ガンボ2011年

12
rawurlencode()はjavascript decodeURI()関数と互換性があります
Clive Paterson

このルールは常に経験的なものですか?つまり、クエリ文字列をエンコードする必要があるときは、常にを使用しますurldecode。次に、URIパス(例/a/path with spaces/)とURIフラグメント(例#fragment)についてはどうでしょうか。私は常にrawurldecodeこれら2つに使用する必要がありますか?
tonix 2018

経験則としては、パス(/ my%20folder /など)はrawurlencode; しかし、POSTのためとGETフィールドは一緒に行くurlencode(?のように/フォルダ=私+フォルダ) `
Soroush Falahati

22

狡猾な名前のurlencode()urldecode()

ただし、およびにurldecode()表示される変数を使用する必要はありません。$_POST$_GET


4
$ _POSTでurldecode()を使用しない理由を詳しく説明してください。昔から問題なくやってきたから。
sid

"name=b&age=c&location=d"AJAX経由でPHPファイルに送信される基本的なパラメーター(例)をエンコードする必要がありますか?
オールドボーイ

9

これが私の使用例です。これには、並外れた量のエンコーディングが必要です。たぶんそれは人為的なものだと思うかもしれませんが、私たちはこれを実稼働で実行します。偶然にも、これはあらゆる種類のエンコーディングをカバーしているので、チュートリアルとして投稿しています。

ユースケースの説明

誰かが私たちのウェブサイトでプリペイドギフトカード(「トークン」)を購入しました。トークンには、トークンを利用するための対応するURLがあります。この顧客は、URLを他の誰かに電子メールで送信したいと考えています。私たちのWebページには、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"
}, 

そしてもちろん、これは上記のJSON表現です$token


同様に、意味的にmailto:は少ない(HTTPではないため)を使用できます$mailToUri 'mailto:?' . http_build_query(['subject'=>$subject, 'body'=>$body], null, '&', PHP_QUERY_RFC3986);
William Entriken


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をご覧ください

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.