¿Cómo codificar correctamente una URL en PHP?

97

Estoy creando una página de búsqueda, donde se escribe una consulta de búsqueda y se envía el formulario search.php?query=your query. ¿Qué función de PHP es la mejor y que debería usar para codificar / decodificar la consulta de búsqueda?

Haga clic en Upvote
fuente
2
¿Tiene algún problema? Los navegadores y PHP ya deberían manejar esto automáticamente (por ejemplo, al poner foo barun campo de texto, crear foo+baren la URL).
Felix Kling
@Felix Voy a llamar al script de búsqueda usandofile_get_contents
Haga clic en Upvote

Respuestas:

183

Para la consulta de URI use urlencode/ urldecode; para cualquier otra cosa use rawurlencode/ rawurldecode.

La diferencia entre urlencodey rawurlencodees que

Gumbo
fuente
application / x-www-form-urlencoded es solo una variante especial de la codificación porcentual y solo se aplica para codificar datos de formularios HTML.
Gumbo
1
@Haga clic en Upvote: no se pueden comparar de esa manera. El formato application / x-www-form-urlencoded es el formato de codificación porcentual, excepto que el espacio está codificado con en +lugar de %20. Y además de eso, application / x-www-form-urlencoded se usa para codificar datos de formularios, mientras que la codificación porcentual tiene un uso más general.
Gumbo
12
rawurlencode () es compatible con JavaScript decodeURI () la función
Clive Paterson
¿Es esta regla siempre la empírica? Quiero decir, cuando necesito codificar una cadena de consulta, siempre uso urldecode. Entonces, ¿qué pasa con la ruta URI (por ejemplo /a/path with spaces/) y el fragmento URI (por ejemplo #fragment). ¿Debería usar siempre rawurldecodepara estos dos?
tonix
Una buena regla general es que para las rutas (Like / my% 20folder /) vaya con rawurlencode; pero para los campos POST y GET, vaya con urlencode(Like /? folder = my + folder) `
Soroush Falahati
22

El urlencode () y urldecode () con nombres ingeniosos .

Sin embargo, no debería necesitar usar urldecode()en variables que aparecen en $_POSTy $_GET.

Oliver Charlesworth
fuente
4
¿Podría explicar por qué urldecode () no debería usarse con $ _POST? porque lo he estado haciendo desde hace años sin ningún problema.
sid
¿Necesito codificar parámetros básicos (por ejemplo "name=b&age=c&location=d") enviados a un archivo PHP a través de AJAX?
oldboy
9

Este es mi caso de uso, que requiere una cantidad excepcional de codificación. Tal vez pienses que fue un truco, pero lo ejecutamos en producción. Coincidentemente, esto cubre todo tipo de codificación, así que lo publico como tutorial.

Descripción del caso de uso

Alguien acaba de comprar una tarjeta de regalo prepaga ("token") en nuestro sitio web. Los tokens tienen las URL correspondientes para canjearlos. Este cliente desea enviar la URL por correo electrónico a otra persona. Nuestra página web incluye un mailtoenlace que les permite hacerlo.

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: lo anterior asume que está enviando a un text/htmldocumento. Si su tipo de medio de salida es text/jsonsimplemente utilícelo $retval['url'] = $mailToUri;porque la codificación de salida es manejada por json_encode().

Caso de prueba

  1. Ejecute el código en un sitio de prueba de PHP ( ¿hay uno canónico que deba mencionar aquí? )
  2. Haga clic en el enlace
  3. Enviar el correo electrónico
  4. Recibe el correo electrónico
  5. Haga clic en ese enlace

Deberías ver:

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

Y, por supuesto, esta es la representación JSON de $tokenarriba.

William Entriken
fuente
De manera equivalente y menos semántica (porque mailto:no es HTTP), puede usar $mailToUri 'mailto:?' . http_build_query(['subject'=>$subject, 'body'=>$body], null, '&', PHP_QUERY_RFC3986);.
William Entriken
0

Puede utilizar las funciones de codificación de URL PHP tiene la

rawurlencode() 

función

ASP tiene el

Server.URLEncode() 

función

En JavaScript puede utilizar el

encodeURIComponent() 

función.

Amranur Rahman
fuente
0

Según el tipo de codificación estándar RFC que desee realizar o si necesita personalizar su codificación, es posible que desee crear su propia clase.

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

Ejemplo de uso:

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

Saldrá:

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

* Obtenga más información sobre los estándares RFC: https://datatracker.ietf.org/doc/rfc3986/ y urlencode vs rawurlencode?

DevWL
fuente