Jak poprawnie zakodować ciąg znaków w PHP?

98

Robię stronę wyszukiwania, na której wpisujesz zapytanie i formularz jest przesyłany search.php?query=your query. Jaka funkcja PHP jest najlepsza i której powinienem używać do kodowania / dekodowania zapytania wyszukiwania?

Kliknij opcję Głos za głosem
źródło
2
Czy masz jakieś problemy? Przeglądarki i PHP powinny już obsługiwać to automatycznie (np. Umieszczając foo barpole tekstowe, tworzy foo+barw adresie URL).
Felix Kling
@Felix Mam zamiar zadzwonić do skryptu wyszukiwania za pomocąfile_get_contents
Kliknij Upvote

Odpowiedzi:

185

W przypadku zapytania URI użyj urlencode/ urldecode; do czegokolwiek innego użyj rawurlencode/ rawurldecode.

Różnica między urlencodei rawurlencodejest taka

Gumbo
źródło
application / x-www-form-urlencoded to tylko specjalny wariant kodowania procentowego i jest stosowany tylko do kodowania danych formularza HTML.
Gumbo,
1
@Click Upvote: Nie można ich porównywać w ten sposób. Application / x-www postać urlencoded formacie jest Procenty kodowania formatu z tym, że przestrzeń jest zakodowany +zamiast %20. Poza tym application / x-www-form-urlencoded jest używany do kodowania danych formularza, podczas gdy kodowanie procentowe ma bardziej ogólne zastosowanie.
Gumbo,
13
rawurlencode () jest kompatybilny z javascript decodeURI () funkcji
Clive Paterson
Czy jest to zawsze reguła empiryczna? Mam na myśli, kiedy muszę zakodować ciąg zapytania, którego zawsze używam urldecode. A co ze ścieżką URI (np. /a/path with spaces/) I fragmentem URI (np #fragment.). Czy powinienem zawsze używać rawurldecodedla tych dwóch?
tonix
Dobrą zasadą jest to, że ścieżki (Like / my% 20folder /) są zgodne z rawurlencode; ale dla pól POST i GET idź z urlencode(Like /? folder = my + folder) `
Soroush Falahati
23

Sprytnie nazwane urlencode () i urldecode () .

Jednak nie powinieneś używać urldecode()na zmiennych, które pojawiają się w $_POSTi $_GET.

Oliver Charlesworth
źródło
4
czy mógłbyś wyjaśnić, dlaczego urldecode () nie powinno być używane z $ _POST. ponieważ robię to od wieków bez żadnych problemów.
sid
czy muszę zakodować podstawowe parametry (np. "name=b&age=c&location=d") przesłane do pliku PHP przez AJAX?
oldboy
11

Oto mój przypadek użycia, który wymaga wyjątkowej ilości kodowania. Może myślisz, że to wymyślone, ale uruchamiamy to na produkcji. Tak się składa, że ​​dotyczy to każdego typu kodowania, więc publikuję jako samouczek.

Opis przypadku użycia

Ktoś właśnie kupił przedpłaconą kartę podarunkową („token”) w naszej witrynie. Tokeny mają odpowiadające im adresy URL umożliwiające ich wykorzystanie. Ten klient chce wysłać adres URL do kogoś innego. Nasza strona internetowa zawiera mailtołącze, które im to umożliwia.

Kod 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>';

Uwaga: powyższe zakłada, że ​​drukujesz do text/htmldokumentu. Jeśli typ nośnika wyjściowego jest text/jsonpo prostu użyj, $retval['url'] = $mailToUri;ponieważ kodowanie wyjściowe jest obsługiwane przez json_encode().

Przypadek testowy

  1. Uruchom kod na stronie testowej PHP ( czy istnieje kanoniczna, o której powinienem tutaj wspomnieć? )
  2. Kliknij w link
  3. Wyślij e-mail
  4. Uzyskaj e-maila
  5. Kliknij ten link

Powinieneś zobaczyć:

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

I oczywiście jest to reprezentacja JSON $tokenpowyżej.

William Entriken
źródło
Równoważnie i mniej semantycznie (ponieważ mailto:nie jest HTTP), możesz użyć $mailToUri 'mailto:?' . http_build_query(['subject'=>$subject, 'body'=>$body], null, '&', PHP_QUERY_RFC3986);.
William Entriken
0

Możesz użyć funkcji kodowania adresów URL PHP ma rozszerzenie

rawurlencode() 

funkcjonować

ASP ma

Server.URLEncode() 

funkcjonować

W JavaScript możesz użyć

encodeURIComponent() 

funkcjonować.

Amranur Rahman
źródło
0

W oparciu o typ standardowego kodowania RFC, które chcesz wykonać, lub jeśli chcesz dostosować kodowanie, możesz utworzyć własną klasę.

/**
 * 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;
        }
    }
}

Użyj przykładu:

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

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

Wyświetli:

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 protected])"

* Dowiedz się więcej o standardach RFC: https://datatracker.ietf.org/doc/rfc3986/ i urlencode vs rawurlencode?

DevWL
źródło