Como codificar corretamente uma string em PHP?

97

Estou fazendo uma página de pesquisa, onde você digita uma consulta de pesquisa e o formulário é enviado search.php?query=your query. Qual função PHP é a melhor e que devo usar para codificar / decodificar a consulta de pesquisa?

Clique em votar positivamente
fonte
2
Você está tendo problemas? Os navegadores e o PHP já devem lidar com isso automaticamente (por exemplo, colocar foo barum campo de texto, criar foo+barna URL).
Felix Kling de
@Felix Vou chamar o script do pesquisador usandofile_get_contents
Clique em Upvote

Respostas:

183

Para a consulta de URI, use urlencode/ urldecode; para qualquer outra coisa, use rawurlencode/ rawurldecode.

A diferença entre urlencodee rawurlencodeé que

quiabo
fonte
application / x-www-form-urlencoded é apenas uma variante especial do Percent-Encoding e só é aplicado para codificar dados de formulário HTML.
Gumbo de
1
@Clique em Upvote: Eles não podem ser comparados dessa forma. O formato application / x-www-form-urlencoded é o formato Percent-Encoding , exceto que o espaço é codificado com em +vez de %20. Além disso, application / x-www-form-urlencoded é usado para codificar os dados do formulário, enquanto o Percent-Encoding tem um uso mais geral.
Gumbo de
12
rawurlencode () é compatível com JavaScript decodeURI () função
Clive Paterson
Esta regra é sempre empírica? Quer dizer, quando preciso codificar uma string de consulta, sempre uso urldecode. Então, que tal o caminho URI (por exemplo /a/path with spaces/) e o fragmento de URI (por exemplo #fragment). Devo sempre usar rawurldecodepara esses dois?
tonix
Uma boa regra prática é que os caminhos (como / minha% 20pasta /) acompanhem rawurlencode; mas para os campos POST e GET vá com urlencode(Like /? pasta = minha + pasta) `
Soroush Falahati
22

O urlencode () e o urldecode () com nomes astutos .

No entanto, você não deve precisar usar urldecode()em variáveis ​​que aparecem em $_POSTe $_GET.

Oliver Charlesworth
fonte
4
você poderia explicar porque urldecode () não deve ser usado com $ _POST. porque eu tenho feito isso há muito tempo, sem problemas.
sid
eu preciso codificar parâmetros básicos (por exemplo "name=b&age=c&location=d") enviados para um arquivo PHP via AJAX?
oldboy
9

Aqui está meu caso de uso, que requer uma quantidade excepcional de codificação. Talvez você pense que foi artificial, mas executamos isso na produção. Coincidentemente, isso cobre todo tipo de codificação, então estou postando como um tutorial.

Descrição do caso de uso

Alguém acabou de comprar um cartão-presente pré-pago ("token") em nosso site. Os tokens têm URLs correspondentes para resgatá-los. Este cliente deseja enviar o URL por e-mail para outra pessoa. Nossa página da web inclui um mailtolink que permite que eles façam isso.

Código 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>';

Nota: o acima pressupõe que você está enviando para um text/htmldocumento. Se o seu tipo de mídia de saída for text/jsonsimplesmente usado $retval['url'] = $mailToUri;porque a codificação de saída é controlada por json_encode().

Caso de teste

  1. Execute o código em um site de teste PHP ( há algum canônico que eu deva mencionar aqui? )
  2. Clique no link
  3. Manda o email
  4. Pegue o email
  5. Clique naquele link

Você deveria ver:

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

E, claro, esta é a representação JSON $tokenacima.

William Entriken
fonte
Equivalentemente, e menos semanticamente (porque mailto:não é HTTP), você pode usar $mailToUri 'mailto:?' . http_build_query(['subject'=>$subject, 'body'=>$body], null, '&', PHP_QUERY_RFC3986);.
William Entriken de
0

Você pode usar funções de codificação de URL. PHP tem o

rawurlencode() 

função

ASP tem o

Server.URLEncode() 

função

Em JavaScript, você pode usar o

encodeURIComponent() 

função.

Amranur Rahman
fonte
0

Com base no tipo de codificação padrão RFC que você deseja executar ou se precisar personalizar sua codificação, você pode criar sua própria 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;
        }
    }
}

Use o exemplo:

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

Irá produzir:

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

* Saiba mais sobre os padrões RFC: https://datatracker.ietf.org/doc/rfc3986/ e urlencode vs rawurlencode?

DevWL
fonte