sirve - php tutorial
¿Por qué el analizador de PHP entiende "$ x++-++ $ x", pero falla en "$ x+++++ $ x"? (3)
El analizador PHP está buscando el signo ++
antes del último signo +
, y la sintaxis ($x++)++
no tiene sentido, debido al hecho de que el operador de incremento debe aplicarse a una variable (y no a un entero, que Es el resultado de los primeros $x++
).
La precedencia de las operaciones del operador se puede encontrar aquí:
http://php.net/manual/en/language.operators.precedence.php
$x+++++$x;
^ php parser starts here, find $x++
^ here there is a new ++, which has hight precedence to the next + char
^ here is the last +, which the php parser will find last.
Cuando los dos ++
, ++
dividen con un signo menos, el código es en realidad $x++ - ++$x
, uno que el analizador de PHP puede entender.
Esta es también la razón por la cual $x++ + ++$x
funciona.
Tengo un motor que realiza algunas operaciones lógicas y matemáticas al tomar fórmulas, operandos y operadores de un archivo. Todas las operaciones se ejecutan en un ámbito de eval
y el resultado final se guarda en otro archivo.
Estos archivos a menudo se transfieren a través de una red, por lo que estoy tratando de minimizarlos eliminando todos los espacios antes y después de las operaciones. Por lo que sé, no hay reglas estrictas al respecto, sin embargo, me topé con este comportamiento:
$x = 1;
$result = $x++-++$x; // works
$result = $x+++++$x; // fails
$result = $x++ + ++$x; // works again
¿Por qué PHP se confunde con la sintaxis "+++++", pero acepta "++ - ++"? ¿Cómo es "más" mejor que "menos"?
¿Hay una lista en cualquier lugar de operadores que sean sensibles a los espacios?
La respuesta es que el analizador busca tokens más largos antes de buscar los más cortos. Por lo tanto, ++++++ se convierte en ++ ++ +, que no es comprensible para el intérprete.
PHP es uno de los muchos idiomas que toma prestada su expresión gramatical de C, por lo que esta nota puede ser de su interés. En el borrador de C11 , la sección 6.4 cláusula 6 dio un ejemplo:
El fragmento de programa x +++++ y se analiza como x ++ ++ + y, lo que infringe una restricción en los operadores de incremento, aunque el análisis x ++ + ++ y pueda producir una expresión correcta.
Un poco más de información complementaria. Cuando un script PHP está "lexed", es decir, cuando se escanea, se examinan los tokens que comprenden el script. Un par de caracteres como "++" significa un token de incremento, de la siguiente manera:
<ST_IN_SCRIPTING>"++" {
RETURN_TOKEN(T_INC);
}
Esta "regla" se encuentra en el archivo Zend / language_scanner.l que acompaña a PHP cuando lo descarga e instala. La única forma en que un script cuando se escanea se vuelve inteligible para el lexer con respecto a las variables pre- o post-incrementales es si hay algún tipo de demarcación como el espaciado para que cada "+" se evalúe adecuadamente en el contexto.
Tenga en cuenta que no es aconsejable escribir código como el siguiente:
<?php
$x=0;
echo $x++ + ++$x;
incluso aunque esté correctamente corregido. La razón para objetar este estilo de codificación es porque puede ser menos evidente para los cerebros humanos en cuanto a lo que realmente está ocurriendo. El orden de evaluación no es lo que puede parecer, es decir, una variable que se incrementa posteriormente y luego se agrega a sí misma con su valor pre-incrementado.
Según los opcodes , los incrementos previos y posteriores se producen antes de que tenga lugar la adición. Además, tenga en cuenta que el incremento posterior devuelve el valor de una variable y luego lo incrementa. Entonces, inicialmente, a $ x se le asigna un valor de 0. Luego, se incrementa de manera que una variable temporal devuelve un valor de cero. Entonces, $ x se incrementa para adquirir un valor de uno. A continuación, $ x se pre-incrementa, por lo que $ x se mueve de uno a dos y su variable temporal se evalúa como dos. Por último, se agregan las dos variables temporales, de modo que 0 + 2 == 2
; Ver here , así como here .
Además, una excelente lectura here .
Por cierto, en este caso, PHP cumple con su lenguaje de programación El C; ver here