Recomendaciones sobre arrays y cosas a evitar

¿Porqué es incorrecto $foo[bar]?

Siempre deben usarse comillas alrededor de un índice de array tipo cadena literal. Por ejemplo, $foo['bar'] es correcto, mientras que $foo[bar] no lo es. ¿Pero porqué? Es común encontrar este tipo de sintaxis en scripts viejos:
<?php
$foo
[bar] = 'enemy'
;
echo 
$foo[bar
];// etc?>
Esto está mal, pero funciona. La razón es que este código tiene una constante indefinida (bar) en lugar de un valor string ('bar' - note las comillas). Puede que en el futuro PHP defina constantes que, desafortunadamente para tal tipo de código, tengan el mismo nombre. Funciona porque PHP automáticamente convierte una cadena pura (un string sin comillas que no corresponda con símbolo conocido alguno) en un string que contiene la cadena pura. Por ejemplo, si no se ha definido una constante llamada bar, entonces PHP reemplazará su valor por la cadena 'bar' y usará ésta última.
Note: Esto no quiere decir que siempre haya que usar comillas en la clave. No use comillas con claves que sean constantes o variables, ya que en tal caso PHP no podrá interpretar sus valores.
<?php
error_reporting
(E_ALL
);ini_set('display_errors'true);ini_set('html_errors'false);// Array simple:$array = array(12);$count count($array);
for (
$i 0$i $count$i
++) {
    echo 
"\nRevisando $i: \n"
;
    echo 
"Mal: " $array['$i'] . "\n"
;
    echo 
"Bien: " $array[$i] . "\n"
;
    echo 
"Mal: {$array['$i']}\n"
;
    echo 
"Bien: {$array[$i]}\n"
;
}
?>
El resultado del ejemplo sería:
Revisando 0:
Notice: Undefined index:  $i in /path/to/script.html on line 9
Mal:
Bien: 1
Notice: Undefined index:  $i in /path/to/script.html on line 11
Mal:
Bien: 1

Revisando 1:
Notice: Undefined index:  $i in /path/to/script.html on line 9
Mal:
Bien: 2
Notice: Undefined index:  $i in /path/to/script.html on line 11
Mal:
Bien: 2
Más ejemplos para demostrar este comportamiento:
<?php// Mostrar todos los erroreserror_reporting(E_ALL);
$arr = array('fruit' => 'apple''veggie' => 'carrot'
);
// Correctoprint $arr['fruit'];  // appleprint $arr['veggie']; // carrot

// Incorrecto. Esto funciona pero también genera un error de PHP de
// nivel E_NOTICE ya que no hay definida una constante llamada fruit
//
// Notice: Use of undefined constant fruit - assumed 'fruit' in...
print $arr[fruit];    
// apple

// Esto define una constante para demostrar lo que pasa. El valor 'veggie'
// es asignado a una constante llamada fruit.
define('fruit''veggie'
);
// Note la diferencia ahoraprint $arr['fruit'];  // appleprint $arr[fruit];    // carrot

// Lo siguiente está bien ya que se encuentra al interior de una cadena. Las constantes no son procesadas al
// interior de cadenas, así que no se produce un error E_NOTICE aquí
print "Hello $arr[fruit]";      
// Hello apple

// Con una excepción, los corchetes que rodean las matrices al
// interior de cadenas permiten el uso de constantes
print "Hello {$arr[fruit]}";    
// Hello carrotprint "Hello {$arr['fruit']}";  // Hello apple

// Esto no funciona, resulta en un error de intérprete como:
// Parse error: parse error, expecting T_STRING' or T_VARIABLE' or T_NUM_STRING'
// Esto por supuesto se aplica también al uso de superglobales en cadenas
print "Hello $arr['fruit']"
;
print 
"Hello $_GET['foo']"
;
// La concatenación es otra opciónprint "Hello " $arr['fruit']; // Hello apple?>
Cuando se habilita error_reporting para mostrar errores de nivel E_NOTICE (como por ejemplo definiendo el valor E_ALL), este tipo de usos serán inmediatamente visibles. Por omisión, error_reporting se encuentra configurado para no mostrarlos.
Tal y como se indica en la sección de sintaxis, lo que existe entre los corchetes cuadrados ('[' y ']') debe ser una expresión. Esto quiere decir que código como el siguiente funciona:
<?phpecho $arr[somefunc($bar)];?>
Este es un ejemplo del uso de un valor devuelto por una función como índice del array. PHP también conoce las constantes:
<?php
$error_descriptions
[E_ERROR]   = "Un error fatal ha ocurrido"
;$error_descriptions[E_WARNING] = "PHP produjo una advertencia";$error_descriptions[E_NOTICE]  = "Esta es una noticia informal";?>
Note que E_ERROR es también un identificador válido, asi como bar en el primer ejemplo. Pero el último ejemplo es equivalente a escribir:
<?php
$error_descriptions
[1] = "Un error fatal ha ocurrido"
;$error_descriptions[2] = "PHP produjo una advertencia";$error_descriptions[8] = "Esta es una noticia informal";?>
ya que E_ERROR es igual a 1, etc.
¿Entonces porqué está mal?
En algún momento en el futuro, puede que el equipo de PHP quiera usar otra constante o palabra clave, o una constante proveniente de otro código puede interferir. Por ejemplo, en este momento no puede usar las palabras empty y default de esta forma, ya que son palabras clave reservadas.
Note: Reiterando, al interior de un valor string entre comillas dobles, es válido no rodear los índices de matriz con comillas, así que "$foo[bar]" es válido. Consulte los ejemplos anteriores para más detalles sobre el porqué, así como la sección sobre procesamiento de variables en cadenas.