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?
Gumbo
Para el uso de consulta de URI urlencode
/urldecode
; para cualquier otro uso rawurlencode
/rawurldecode
.
La diferencia entre urlencode
y rawurlencode
es eso
urlencode
codifica de acuerdo con application/x-www-form-urlencoded (el espacio está codificado con+
) tiemporawurlencode
codifica según el plano Codificación porcentual (el espacio está codificado con%20
).
-
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 siemprerawurldecode
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 conurlencode
(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
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
- Ejecute el código en un sitio de prueba de PHP (¿Hay alguna canónica que deba mencionar aquí?)
- Haga clic en el enlace
- enviar el correo electrónico
- Obtener el correo electrónico
- 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
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?
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”.
$array = [
'query' => 'your query',
'example' => null,
'Qbert says:' => '&%=#?/'
];
echo http_build_query($array);
echo "\n---\n";
echo http_build_query($array, '', '&');
Producción:
query=your+query&Qbert+says%3A=%26%25%3D%23%3F%2F
---
query=your+query&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 &
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.
¿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, creafoo+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