2009-10-28 20 views
16

¿Cómo puedo comprobar si una cadena tiene codificación URL?Prueba si la cadena está codificada en URL en PHP

¿Cuál de los siguientes enfoques es mejor?

  • Busca en la cadena de caracteres que se codifican, que no son, y si las hay, entonces no es codificado, o
  • usar algo como esto lo que he hecho:

function is_urlEncoded($string){ 
$test_string = $string; 
while(urldecode($test_string) != $test_string){ 
    $test_string = urldecode($test_string); 
} 
return (urlencode($test_string) == $string)?True:False; 
} 

$t = "Hello World > how are you?"; 
if(is_urlEncoded($sreq)){ 
print "Was Encoded.\n"; 
}else{ 
print "Not Encoded.\n"; 
print "Should be ".urlencode($sreq)."\n"; 
} 

el código anterior funciona, pero no en los casos en que la cadena ha sido codificados por partida doble, como en estos ejemplos:

  • $t = "Hello%2BWorld%2B%253E%2Bhow%2Bare%2Byou%253F";
  • $t = "Hello+World%2B%253E%2Bhow%2Bare%2Byou%253F";
+1

¿Cómo se codificará la cadena en el momento en que lo ve su script PHP? ¿El problema es realmente que su script necesita decodificar URL una cadena entrante, o es el problema que su secuencia de comandos necesita para no codificar por duplicado un href de un enlace o un valor de entrada, por ejemplo? –

+0

¿Qué le parece usar el código url y compararlo con la cadena original? Si coinciden, aún no está codificado. – thedjaney

Respuesta

10

Nunca sabrá con certeza si una cadena tiene codificación URL o si se supone que tiene la secuencia %2B en ella. En cambio, probablemente dependa del origen de la cadena, es decir, si fue hecha a mano o de alguna aplicación.

Es mejor buscar en la cadena caracteres codificados, que no lo son, y si existen, no está codificado.

creo que este es un enfoque mejor, ya que se haría cargo de las cosas que se han hecho mediante programación (suponiendo que la aplicación no se habría dejado un carácter no codificado detrás).

Una cosa que será confusa aquí ... Técnicamente, el % "debe ser" codificado si estará presente en el valor final, ya que es un carácter especial. Puede que tenga que combinar sus enfoques para buscar caracteres que deben codificarse, así como para validar que la cadena se decodifique correctamente si no se encuentra ninguno.

+0

"se supone que tiene la secuencia'% 2B' en él ", su decodificación-verificación-codificación-verificación es un intento de contrarrestar esto (decodificar en espacio, codificar a% 2B, no codificado) – falstro

+0

Es cierto, a menos que la intención fuera pasa esa secuencia como el valor final ... Tu ejemplo aritmético es un mejor ejemplo en el que eso fallaría. En cambio, al buscar caracteres que "deberían haber" sido codificados, la aplicación obtiene una mejor pista si la cadena ya está codificada. – jheddings

4

Creo que no hay manera infalible para hacerlo. Por ejemplo, considere lo siguiente:

$t = "A+B"; 

es que una URL codificada "A B" o necesita ser codificado de "A% 2BB"?

3

así, el término "URL codificada" es un poco vago, quizá de verificación de expresiones regulares simples hará el truco

$is_encoded = preg_match('~%[0-9A-F]{2}~i', $string); 
+1

esto falla "this + string + is + url + codified" – falstro

+2

hmm, ¿pensé que '+' es una codificación válida de espacio en urls? – falstro

3

No hay manera confiable de hacer esto, ya que hay cadenas que se mantienen la misma a través de la proceso de codificación, es decir, ¿está codificado "abc" o no? No hay una respuesta clara. Además, como ha visto, algunos caracteres tienen codificaciones múltiples ... Pero ...

Su esquema de decodificación-verificación-codificación-verificación falla debido al hecho de que algunos caracteres pueden estar codificados de más de una manera. Sin embargo, una pequeña modificación a su función debería ser bastante confiable, solo verifique si la decodificación modifica la cadena, si lo hace, fue codificada.

No será una prueba tonta, por supuesto, ya que "10 + 20 = 30" volverá verdadero (+ se convierte en espacio), pero en realidad solo estamos haciendo aritmética. Supongo que esto es lo que tu esquema está intentando contrarrestar, lamento decir que no creo que haya una solución perfecta.

HTH.

Editar:
Mientras encionó en mi comentario (acaba de reiterar aquí para mayor claridad), un buen compromiso sería probablemente para comprobar si hay caracteres no válidos en su URL (por ejemplo, el espacio), y si hay algunos, lo mejor no codificado Si no hay ninguno, intente decodificar y ver si la cadena cambia. Esto todavía no manejará la aritmética anterior (lo cual es imposible), pero con suerte será suficiente.

+0

"Sin embargo, una pequeña modificación en su función debería ser bastante confiable, solo verifique si la decodificación modifica la cadena, si es así, fue codificada". Pensé esto, sin embargo, si esta es la cadena "Hola, mundo, ¿cómo estás?", La decodificación producirá un cambio, pero no se habrá codificado por completo. – Psytronic

+0

@Psytronic: Muy cierto, ese + es un inseparable, ¿no? Si puede encontrar una forma de determinar si es una URL válida, entonces la decodificación para verificar un cambio probablemente sea una mejor solución. Debería poder diseñar una expresión regular para buscar caracteres "malos" como el espacio (si no es válido, no está codificado). – falstro

33

tengo un truco:

Esto se puede hacer para evitar que codifican por partida doble. Cada vez que decodifique primero, vuelva a codificar;

$string = urldecode($string); 

Después, realice de nuevo

$string = urlencode($string); 

La realización de esta manera podemos evitar la doble codificación :)

+1

¡Eso está mal! La URL que se decodificó una vez, no se puede codificar de la misma manera. Para obtener más información, consulte: http://blog.lunatech.com/2009/02/03/what-every-web-developer-must-know-about-url-encoding Como ejemplo "a + b" como parámetro de ruta es válido. Entonces, si decodificas, tienes la misma cadena (a + b), y luego, después del resultado del codificador, aparece "a% 2Bb". – instead

+1

Esto causará problemas. P.ej. si tiene una cadena de texto sin formato con un signo más como este: "TestString Super Mega +" El signo más se eliminará, si lo canaliza a través de urldecode(); – suther

1

enviar una variable que las banderas de la decodificación cuando ya la obtención de datos a partir de una URL.

?path=folder/new%20file.txt&decode=1 
2

¿Qué hay de:

if (urldecode(trim($url)) == trim($url)) { $url_form = 'decoded'; } 
    else { $url_form = 'encoded'; } 

no funcionará con doble codificación, pero esto está fuera del alcance de todas formas supongo?

+0

intente con la cadena "1 + 1 = 2" – John

9

Aquí hay algo que acabo de armar.

if (urlencode(urldecode($data)) === $data){ 
    echo 'string urlencoded'; 
} else { 
    echo 'string is NOT urlencoded'; 
} 
+0

Buena solución bastante fácil ... simple, limpia, avance rápido ^^. – suther

+0

@suther por favor pruébelo con varias entradas, no lo recuerdo pero a veces no funciona como se esperaba. – AMB

0

estoy usando la siguiente prueba para ver si las cadenas se han urlencoded:

if(urlencode($str) != str_replace(['%','+'], ['%25','%2B'], $str)) 

Si una cadena ya se ha urlencoded, los únicos personajes que cambiaron por doble codificación son% (que comienza todas las cadenas de caracteres codificados) y + (que reemplaza los espacios). Cámbielos de nuevo y debe tener la cadena original.

Avísame si esto funciona para ti.

2

@ user187291 código funciona y solo falla cuando + no está codificado.

Sé que esta es una publicación muy antigua. Pero esto funcionó para mí.

$is_encoded = preg_match('~%[0-9A-F]{2}~i', $string); 
if($is_encoded) { 
$string = urlencode(urldecode(str_replace(['+','='], ['%2B','%3D'], $string))); 
} else { 
    $string = urlencode($string); 
} 
+0

Si la codificación es como se describe en RFC 3986, la expresión regular debe ser otra –

-1

privada estática booleano isEncodedText (String val, cuerdas ... codificación) lanza UnsupportedEncodingException { cadena decodedText = URLDecoder.decode (val, TransformFetchConstants.DEFAULT_CHARSET);

if(encoding != null && encoding.length > 0){ 
     decodedText = URLDecoder.decode(val, encoding[0]); 
    } 

    String encodedText = URLEncoder.encode(decodedText); 

    return encodedText.equalsIgnoreCase(val) || !decodedText.equalsIgnoreCase(val); 

} 
Cuestiones relacionadas