php - ¿Por qué esta llamada a strstr no devuelve falso?
string casting (2)
Me he topado con un problema con strstr en un antiguo código de base heredado. Hay mucho código, pero básicamente el caso de prueba se reduciría a esto:
$value = 2660;
$link = ''affiliateid=1449&zoneid=6011&placement_id=11736&publisher_id=1449&period_preset=yesterday&period_start=2017-03-27&period_end=2017-03-27'';
var_dump(strstr($link, $value));
Espero que esto devuelva false
ya que "2660" no está en la cadena, sin embargo, devuelve d=1449&zoneid=6011&placement_id=11736&publisher_id=1449&period_preset=yesterday&period_start=2017-03-27&period_end=2017-03-27
.
Me doy cuenta de que $value
debería ser una cadena, pero aún no entiendo por qué PHP no la convierte en una cadena y por qué encuentra este número en el enlace.
En realidad, si intento con $value = ''2660'';
devuelve false
como se esperaba.
¿Alguna idea de lo que está pasando?
Respuesta corta
Cuando ejecuta strstr($str, 2660)
la $needle
se resuelve en el carácter " d " al llamar a chr(2660)
y, por lo tanto, se detiene en la primera " d " que se encuentra en el $str
dado, en este caso justo en el 11º personaje.
¿Por qué llamamos a chr(2660)
?
Porque cuando $needle
no es una cadena, strstr
convierte ese argumento en un entero y usa el carácter correspondiente para esa posición desde el código ASCII extendido donde chr(2660)
es " d " .
Si la aguja no es una cadena, se convierte en un entero y se aplica como el valor ordinal de un carácter.
Pero, ¿por qué chr(2660)
devuelve " d " cuando " d " es ord(100)
?
Debido a que los valores que se encuentran fuera del rango válido [0-255]
serán a nivel de bit y se usarán con 255
, que es equivalente al siguiente algoritmo [source]
while ($ascii < 0) {
$ascii += 256;
}
$ascii %= 256;
Entonces, 2660
convierte en 100
, y luego cuando se pasa a strstr
se usa como el valor ordinal del personaje y busca el carácter " d " .
¿Confuso? Si También esperaba que se convirtiera en una cadena, pero eso es lo que obtenemos al asumir las cosas en la programación. Esto, al menos, está documentado; te sorprendería la cantidad de veces que sucede algo extraño y no se encuentra una explicación oficial. Al menos no tan fácilmente como siguiendo el mismo enlace que proporcionó.
¿Por qué se llama strstr
?
Hice un poco de investigación y encontré esta gema (Justificación para el Estándar Nacional Americano para Sistemas de Información - Lenguaje de Programación - C) desde 1989, donde nombraron todas las funciones relacionadas con cadenas con el prefijo str
que es lógico, luego ya que la fuente de PHP está escrita en C, explicará por qué se ha llevado. Mi mejor conjetura es que estamos buscando una cadena dentro de otra cadena , dicen:
La función strstr es una invención del comité. Se incluye como un gancho para algoritmos de subcadena eficientes, o para instrucciones de subcadena incorporadas.
Documentos útiles
Creo que esto responde a tu pregunta:
aguja
Si la aguja no es una cadena, se convierte en un entero y se aplica como el valor ordinal de un carácter.
Editar por los comentarios:
chr(2660)
devuelve el carácter d
, que de hecho está en el pajar y es por eso que no devolverá falso como esperabas.