¿Cómo puedo codificar URL correctamente una cadena en PHP?

7 minutos de lectura

Avatar de usuario de Ali
Ali

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

  • ¿Experimentas algún problema? Los navegadores y PHP ya deberían manejar esto automáticamente (por ejemplo, poner foo bar en un campo de texto, crea foo+bar en la URL).

    – Félix Kling

    20 de enero de 2011 a las 8:33


  • @Felix Voy a llamar al script del buscador usando file_get_contents

    – Alí

    20 de enero de 2011 a las 8:36

Avatar de usuario de Gumbo
Gumbo

Para el uso de consulta de URI urlencode/urldecode; para cualquier otro uso rawurlencode/rawurldecode.

La diferencia entre urlencode y rawurlencode es eso

  • application/x-www-form-urlencoded es solo una variante especial del Codificación porcentual y solo se aplica para codificar datos de formularios HTML.

    – Gumbo

    20 de enero de 2011 a las 8:44

  • @Click Upvote: No se pueden comparar de esa manera. los application/x-www-form-urlencoded formato es la Codificación porcentual formato excepto que el espacio está codificado con + en vez de %20. Y además de eso, application/x-www-form-urlencoded se utiliza para codificar datos de formulario mientras que el Codificación porcentual tiene un uso más general.

    – Gumbo

    20 de enero de 2011 a las 10:25

  • rawurlencode() es compatible con javascript decodificarURI() función

    –Clive Paterson

    3 de marzo de 2015 a las 6:40

  • ¿Esta regla es 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 fragmento de URI (p. ej. #fragment). ¿Debería usar siempre rawurldecode para estos dos?

    – tonix

    12/09/2018 a las 16:53

  • Una buena regla general es que para las rutas (como /mi%20carpeta/) vaya con rawurlencode; pero para los campos POST y GET vaya con urlencode (Como /?carpeta=mi+carpeta)`

    – Soroush Falahati

    29 de enero de 2019 a las 15:45


El astutamente llamado códigourlen() y urldecode().

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

  • ¿Podría explicar por qué urldecode() no debe usarse con $_POST? porque he estado haciendo eso desde las edades sin ningún problema.

    – sid

    21 de mayo de 2019 a las 13:18

  • ¿Necesito codificar parámetros básicos (p. ej. "name=b&age=c&location=d") enviado a un archivo PHP a través de AJAX?

    – chico mayor

    29 de julio de 2019 a las 1:07

Avatar de usuario de William Entriken
Guillermo Entriken

Aquí está mi caso de uso, que requiere una cantidad excepcional de codificación. Tal vez pienses que es artificial, pero ejecutamos esto en producción. Coincidentemente, esto cubre todos los tipos de codificación, por lo que estoy publicando como un 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 quiere enviar la URL por correo electrónico a otra persona. Nuestra página web incluye un mailto enlace que les permite hacer eso.

codigo 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 supone que está enviando a un text/html documento. Si su tipo de medio de salida es text/json entonces simplemente usa $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 alguna canónica que deba mencionar aquí?)
  2. Haga clic en el enlace
  3. enviar el correo electrónico
  4. Obtener el correo electrónico
  5. Haga clic en ese enlace

Debería ver:

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

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

  • Equivalentemente, y menos semánticamente (porque mailto: no es HTTP), puede usar $mailToUri 'mailto:?' . http_build_query(['subject'=>$subject, 'body'=>$body], null, '&', PHP_QUERY_RFC3986);.

    – William Entriken

    21 de agosto de 2019 a las 13:34

Avatar de usuario de Amranur Rahman
Amranur Rahman

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

rawurlencode()

función.

ASP.NET tiene el

Server.URLEncode()

función.

En JavaScript, puede utilizar el

encodeURIComponent()

función.

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

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=me@liszka.com)"

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

Avatar de usuario de Peter Mortensen
Pedro Mortensen

Ya sabes cómo la gente sigue diciendo cosas como: “Nunca elabores manualmente una cadena JSON en PHP, siempre llama json_encode() para la estabilidad/confiabilidad.”?

Bueno, si está creando una cadena de consulta, entonces digo: “Nunca elabore manualmente una cadena de consulta de URL en PHP; siempre llame http_build_query() para la estabilidad/confiabilidad”.

Manifestación:

$array = [
    'query' => 'your query',
    'example' => null,
    'Qbert says:' => '&%=#?/'
];

echo http_build_query($array);

echo "\n---\n";

echo http_build_query($array, '', '&amp;');

Producción:

query=your+query&Qbert+says%3A=%26%25%3D%23%3F%2F
---
query=your+query&amp;Qbert+says%3A=%26%25%3D%23%3F%2F

La letra pequeña de esta función es que si un elemento en la matriz de entrada tiene un null valor, entonces ese elemento no se incluirá en la cadena de salida.

Aquí hay una respuesta educativa sobre el Sitio de intercambio de pila de Joomla que fomenta el uso de &amp; como delimitador personalizado: ¿Por qué las cadenas de consulta de URL de Joomla suelen estar delimitadas con “&” en lugar de “&”?

Empaquetar inicialmente los datos de la cadena de consulta en forma de matriz ofrece una estructura compacta y legible, luego la llamada de http_build_query() hace el trabajo duro y puede prevenir la corrupción de datos. Generalmente opto por esta técnica incluso para la construcción de cadenas de consulta pequeñas.

¿Ha sido útil esta solución?