Comment encoder correctement une URL en PHP?

97

Je crée une page de recherche, où vous tapez une requête de recherche et le formulaire est soumis search.php?query=your query. Quelle fonction PHP est la meilleure et que je devrais utiliser pour encoder / décoder la requête de recherche?

Cliquez sur Upvote
la source
2
Rencontrez-vous des problèmes? Les navigateurs et PHP devraient déjà gérer cela automatiquement (par exemple en mettant foo bardans un champ de texte, crée foo+bardans l'URL).
Felix Kling
@Felix Je vais appeler le script de recherche en utilisantfile_get_contents
Cliquez sur Upvote

Réponses:

183

Pour la requête URI, utilisez urlencode/ urldecode; pour toute autre utilisation, utilisez rawurlencode/ rawurldecode.

La différence entre urlencodeet rawurlencodeest que

Gombo
la source
application / x-www-form-urlencoded n'est qu'une variante spéciale du pourcentage d'encodage et n'est appliqué que pour encoder les données de formulaire HTML.
Gumbo
1
@Click Upvote: Ils ne peuvent pas être comparés de cette façon. Le format application / x-www-form-urlencoded est le format Percent-Encoding sauf que l'espace est encodé avec +au lieu de %20. Et en plus de cela, application / x-www-form-urlencoded est utilisé pour encoder les données de formulaire tandis que le Percent-Encoding a un usage plus général.
Gumbo
12
rawurlencode () est compatible avec javascript decodeURI () fonction
Paterson Clive
Cette règle est-elle toujours empirique? Je veux dire, quand j'ai besoin d'encoder une chaîne de requête, j'utilise toujours urldecode. Ensuite, qu'en est-il du chemin URI (par exemple /a/path with spaces/) et du fragment d'URI (par exemple #fragment). Dois-je toujours utiliser rawurldecodepour ces deux?
tonix
Une bonne règle de base est que pour les chemins (comme / mon% 20folder /) allez avec rawurlencode; mais pour les champs POST et GET, allez avec urlencode(Like /? folder = my + folder) `
Soroush Falahati
22

Les astucieusement nommés urlencode () et urldecode () .

Cependant, vous ne devriez pas avoir besoin d'utiliser des urldecode()variables qui apparaissent dans $_POSTet $_GET.

Oliver Charlesworth
la source
4
pourriez-vous expliquer pourquoi urldecode () ne doit pas être utilisé avec $ _POST. parce que je fais ça depuis des lustres sans aucun problème.
sid
dois-je encoder des paramètres de base (par exemple "name=b&age=c&location=d") envoyés à un fichier PHP via AJAX?
oldboy
9

Voici mon cas d'utilisation, qui nécessite une quantité exceptionnelle d'encodage. Peut-être que vous pensez que c'est artificiel, mais nous le faisons en production. Par coïncidence, cela couvre tous les types d'encodage, je publie donc sous forme de tutoriel.

Description du cas d'utilisation

Quelqu'un vient d'acheter une carte-cadeau prépayée («jeton») sur notre site Web. Les jetons ont des URL correspondantes pour les utiliser. Ce client souhaite envoyer l'URL par e-mail à quelqu'un d'autre. Notre page Web comprend un mailtolien qui leur permet de le faire.

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

Remarque: ce qui précède suppose que vous imprimez dans un text/htmldocument. Si votre type de support de sortie est text/jsonalors simplement utilisé $retval['url'] = $mailToUri;car le codage de sortie est géré par json_encode().

Cas de test

  1. Exécutez le code sur un site de test PHP ( y en a-t-il un canonique que je devrais mentionner ici? )
  2. Cliquer sur le lien
  3. Envoyez l'e-mail
  4. Recevoir l'e-mail
  5. Cliquez sur ce lien

Tu devrais voir:

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

Et bien sûr, c'est la représentation JSON $tokenci - dessus.

William Entriken
la source
De manière équivalente, et moins sémantiquement (car ce mailto:n'est pas HTTP), vous pouvez utiliser $mailToUri 'mailto:?' . http_build_query(['subject'=>$subject, 'body'=>$body], null, '&', PHP_QUERY_RFC3986);.
William Entriken
0

Vous pouvez utiliser les fonctions d'encodage d'URL PHP a le

rawurlencode() 

fonction

ASP a le

Server.URLEncode() 

fonction

En JavaScript, vous pouvez utiliser le

encodeURIComponent() 

fonction.

Amranur Rahman
la source
0

En fonction du type d'encodage standard RFC que vous souhaitez effectuer ou si vous devez personnaliser votre encodage, vous pouvez créer votre propre classe.

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

Utilisez l'exemple:

$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);

Sortira:

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

* En savoir plus sur les normes RFC: https://datatracker.ietf.org/doc/rfc3986/ et urlencode vs rawurlencode?

DevWL
la source