Як правильно URL кодувати рядок у PHP?


97

Я роблю сторінку пошуку, де ви вводите пошуковий запит і форма подається search.php?query=your query. Яка функція PHP найкраща і яку я повинен використовувати для кодування / декодування пошукового запиту?


2
Чи виникають у вас проблеми? Браузери та PHP вже повинні це обробляти автоматично (наприклад, введення foo barтекстового поля, створення foo+barURL-адреси).
Фелікс Клінг,

@Felix Я збираюся зателефонувати до сценарію пошуку, натиснувшиfile_get_contents
Натисніть "За" за

Відповіді:


183

Для запиту URI використовуйте urlencode/ urldecode; для чогось іншого використовувати rawurlencode/ rawurldecode.

Різниця між urlencodeі rawurlencodeполягає в тому


application / x-www-form-urlencoded - це лише спеціальний варіант кодування відсотків і застосовується лише для кодування даних форми HTML.
Гамбо

1
@Click Upvote: їх не можна порівнювати таким чином. Формат application / x-www-form-urlencoded - це формат Percent-Encoding , за винятком того, що простір закодовано +замість %20. Крім того, application / x-www-form-urlencoded використовується для кодування даних форми, тоді як Percent-Encoding має більш загальне використання.
Гамбо

12
rawurlencode () поєднає з яваскрипт decodeURI () функцією
Клайв Патерсон

Чи завжди це правило є емпіричним? Я маю на увазі, коли мені потрібно кодувати рядок запиту, який я завжди використовую urldecode. Тоді як щодо шляху URI (наприклад /a/path with spaces/) та фрагмента URI (наприклад #fragment). Чи завжди мені використовувати rawurldecodeдля цих двох?
tonix

Хорошим емпіричним правилом є те, що для шляхів (Like / my% 20folder /) слід використовувати rawurlencode; але для полів POST та GET використовуйте urlencode(Like /? folder = my + folder) `
Сороуш Фалахаті,

22

Хитро названі urlencode () та urldecode () .

Однак вам не потрібно використовувати urldecode()для змінних, які відображаються в $_POSTта $_GET.


4
не могли б ви пояснити, чому urldecode () не слід використовувати з $ _POST. тому що я це роблю споконвіку без жодних проблем.
sid

чи потрібно кодувати основні параметри (наприклад "name=b&age=c&location=d"), надіслані у файл PHP через AJAX?
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"
}, 

І, звичайно, це представлення JSON $tokenвище.


Еквівалентно і менш семантично (оскільки mailto:це не HTTP) ви можете використовувати $mailToUri 'mailto:?' . http_build_query(['subject'=>$subject, 'body'=>$body], null, '&', PHP_QUERY_RFC3986);.
Вільям Ентрікен

0

Ви можете використовувати функції кодування URL-адреси, PHP має

rawurlencode() 

функція

ASP має

Server.URLEncode() 

функція

У JavaScript ви можете використовувати

encodeURIComponent() 

функція.


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?

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.