todas significa que operadores operador las funciones etiquetas codigo aritmeticos php specifications

significa - ¿Cómo puede "[" ser un operador en la especificación del lenguaje PHP?



todas las etiquetas de php (3)

En PHP puede inicializar matrices vacías con [] para saber cómo definir una matriz que define la precedencia del siguiente carácter sobre cómo inicializar la matriz.

Como las matrices son parte de la estructura de sintaxis, se realizan antes de cualquier matemática, simplemente tiene una precedencia más alta que otros operadores de cálculo por esa razón.

var_dump([5, 6, 7] + [1, 2, 3, 4]); # 5674 - The array''s must be known before applying the operator

Sin embargo, con toda honestidad, realmente no entiendo la pregunta. En la mayoría de los lenguajes de programación, [ y ] están asociados con matrices, que es parte de la sintaxis básica que siempre tiene una alta prioridad (si no la más alta)

En la página web http://php.net/manual/en/language.operators.precedence.php , el segundo nivel de precedencia más alto contiene un operador asociativo de la izquierda llamado [ .

No entiendo eso. ¿Es el [ utilizado para acceder / modificar las entradas de la matriz, como en $myArray[23] ? No puedo imaginar ningún fragmento de código donde necesitemos saber la "precedencia" de otros operadores, o donde la "asociatividad" de [ sería útil.


Esta es una pregunta muy válida.

1. Precedencia entre [...]

Primero, nunca hay una ambigüedad con respecto a lo que PHP debería evaluar primero cuando mira el lado derecho de [ , ya que el soporte requiere un cierre que lo acompañe, por lo que cada operador en el medio tiene precedencia sobre el soporte de apertura.

Ejemplo:

$a[1+2]

El + tiene prioridad, es decir, el primero 1 + 2 debe evaluarse antes de que PHP pueda determinar qué elemento recuperar de $ a .

Pero la lista de precedencia del operador no se trata de esto.

2. Asociatividad

En segundo lugar, hay un orden de evaluación de pares consecutivos de [] , como aquí:

$b[1][2]

PHP primero evaluará $b[1] y luego aplicará [2] a eso. Esta es una evaluación de izquierda a derecha y es lo que se pretende con la asociatividad izquierda .

Pero la cuestión que nos ocupa no es tanto acerca de la asociatividad, sino de la precedencia con respecto a otros operadores.

3. Precedencia sobre los operadores en el lado izquierdo

La lista indica que los operadores clone y new tienen precedencia sobre [ , y esto no es fácil de probar.

En primer lugar, la mayoría de las construcciones donde se combinarían las new con corchetes se consideran sintaxis no válida. Por ejemplo, ambas declaraciones:

$a = new myClass()[0]; $a = new myClass[0];

dará un error de análisis:

error de sintaxis, inesperado ''[''

PHP requiere que agregue paréntesis para que la sintaxis sea válida. Entonces no hay forma de que podamos probar las reglas de precedencia como esta.

Pero hay otra forma, al usar una variable que contiene un nombre de clase:

$a = new $test[0];

Esta es una sintaxis válida, pero ahora el desafío es crear una clase que cree algo que actúe como una matriz.

Esto no es trivial, ya que una propiedad de objeto se referencia de esta manera: obj->prop , no como obj["prop"] . Sin embargo, uno puede usar la clase ArrayObject , que puede tratar con corchetes. La idea es extender esta clase y redefinir el método offsetGet para asegurarse de que un objeto recién hecho de esa clase tenga elementos de matriz para devolver.

Para hacer objetos imprimibles, terminé usando el método mágico __toString , que se ejecuta cuando un objeto necesita ser lanzado a una cadena.

Así que se me ocurrió esta configuración, definiendo dos clases similares:

class T extends ArrayObject { public function __toString() { return "I am a T object"; } public function offsetGet ($offset) { return "I am a T object''s array element"; } } class TestClass extends ArrayObject { public function __toString() { return "I am a TestClass object"; } public function offsetGet ($offset) { return "I am a TestClass object''s array element"; } } $test = "TestClass";

Con esta configuración, podemos probar algunas cosas.

Prueba 1

echo new $test;

Esta instrucción crea una nueva instancia de TestClass , que luego debe convertirse en cadena, por lo que se llama al método __toString en esa nueva instancia, que devuelve:

Soy un objeto TestClass

Esto es como se esperaba

Prueba 2

echo (new $test)[0];

Aquí comenzamos con las mismas acciones, ya que los paréntesis obligan a la new operación a ejecutarse primero. Esta vez, PHP no convierte el objeto creado en cadena, sino que solicita el elemento 0 de la matriz. Esta solicitud es respondida por el método offsetGet , por lo que la declaración anterior produce:

Soy un elemento de matriz de un objeto TestClass

Prueba 3

echo new ($test[0]);

La idea es forzar el orden de ejecución opuesto. Lamentablemente, PHP no permite esta sintaxis, por lo que deberá dividir la declaración en dos para obtener el orden de evaluación deseado:

$name = $test[0]; echo new $name;

Entonces ahora [ se ejecuta primero, tomando el primer carácter del valor de $ test , es decir, "T" , y luego se aplica new a eso. Es por eso que también definí una clase T. El echo llama a __toString en esa instancia, lo que produce:

Soy un objeto T

Ahora viene la prueba final para ver cuál es el orden cuando no hay paréntesis presentes:

Prueba 4

echo new $test[0];

Esta es una sintaxis válida, y ...

4. Conclusión

El resultado es:

Soy un objeto T

De hecho, PHP aplicó el [ antes del new operador, a pesar de lo que se establece en la http://php.net/manual/en/language.operators.precedence.php del http://php.net/manual/en/language.operators.precedence.php !

5. Comparando el clone con el new

El operador de clone tiene un comportamiento similar en combinación con [ . Por extraño que parezca, clone y new no son completamente iguales en términos de reglas de sintaxis. Repetición de la prueba 2 con clone :

echo (clone $test)[0];

produce un error de análisis:

error de sintaxis, inesperado ''[''

Pero la prueba 4 repetida con clone muestra que [ tiene prioridad sobre ella.

@bishop informó que esto reproduce el error de documentación # 61513: "la precedencia del operador de clone es incorrecta" .


Simplemente significa que la variable de matriz (asociatividad izquierda - $ primero) se evaluará antes que la clave de matriz (asociatividad derecha - $ 2)

$first[$second]

Esto tiene mucho sentido cuando la matriz tiene múltiples dimensiones

$first[$second][$third][$fourth]