2011-03-17 21 views

Respuesta

2

PHP tiene constantes definibles, pero eso no es realmente muy útil en este contexto.

Así que no. Use cadenas como llaves.

+0

Como esta fue una respuesta aceptada, me gustaría aclarar que PHP define o las constantes no son equivalentes a los símbolos de Ruby en muchos aspectos, excepto que deben ser expresiones constantes. – Matthew

1

PHP no tiene nada que ver con los símbolos, e incluso las constantes funcionan significativamente diferente en PHP que en ruby. Las teclas de matriz deben ser de cadena o numéricas. Puede asignar una cadena o número a una constante, y luego "usar" la constante como la tecla de matriz. Sin embargo, las constantes son estáticas en PHP, por lo que puede no ser lo que desea, requiere más código "repetitivo" y la clave de matriz real seguirá siendo una cadena o un número (según el valor de la constante).

2

Si su preocupación es la sobrecarga de utilizar cadenas como teclas de matriz y el hecho de que la matriz se copia en vez de pasar como referencia cada vez, puedo sugerirle que use stdClass, que es básicamente una clase de objeto que se puede modificar dinámicamente, similar a una matriz, pero se comporta como un objeto.

1

No, PHP no tiene nada como esto. La aproximación más cercana en PHP sería usar cadenas de comillas simples para sus claves hash, solo para asegurarse de que no hubiera "interpolaciones" en ellas.

algunos ejemplos:

  • $arr[key] - esto funcionaría como $arr['key'] en la mayoría de los casos, pero tiene dos inconvenientes: a) si efectivamente existe una constante definida (por ejemplo, define('key', 'rubbish') - Accederá . $arr['rubish'] lo tanto, es simplemente insegura b) que produciría mensajes de "PHP Notice" (a menos que se suprimen los avisos)

  • $arr[@key] -. al igual que antes, pero sin avisos. De hecho, la supresión de errores es muy mala en términos de mantenibilidad.

  • $arr["key"] - forma absolutamente válida, a menos que tenga algunos símbolos especiales dentro de la cadena de comillas dobles. Por ejemplo: "ab\ntc" != 'ab\ntc', "ab$c" != 'ab$c' y así sucesivamente. Pero es un poco paranoico pensar en tales casos, creo.

  • $arr['key'] - esto es, en mi opinión, el más cercano a Ruby's arr[:key] que podría obtener en PHP.

0

Puede usar objetos simples para tener un efecto similar a los símbolos en ruby. Algunas funciones de la base de datos tienen una opción FETCH_OBJECT para emular este efecto.

class StoreMe { 
    public $A; 
    public $B; 
    public $C; 
    public $D; 
} 

La principal ventaja de los símbolos es el uso de las teclas hash para optimizar el rendimiento y el uso de la memoria. Como PHP usa "Copiar al escribir" para almacenar variables, las cadenas pueden ser equivalentes, como símbolos en ruby. Pero PHP usa algún tipo de tabla de traducción para obtener el índice de una matriz a partir de una clave hash.Entonces, cada pequeño conjunto tiene una cierta sobrecarga.

Testscript

escribí este pequeño script para probar la huella de memoria con PHP.

error_log("Start: " . memory_get_usage()); 
$iterations = 10000; 

$hash = []; 
for ($i=0; $i<$iterations; $i++) { 
    $hash[] = [ 
     "A" => "Test", 
     "B" => "Test", 
     "C" => "Test", 
     "D" => "Test", 
    ]; 
} 
error_log("String: " . memory_get_usage());  
$hash = null; 
error_log("Reset: " . memory_get_usage()); 

$hash = []; 
for ($i=0; $i<$iterations; $i++) { 
    $hash[] = [ 
     "Test", 
     "Test", 
     "Test", 
     "Test", 
    ]; 
} 
error_log("Raw: " . memory_get_usage()); 
$hash = null; 
error_log("Reset: " . memory_get_usage()); 

$hash = []; 
$copy = [ 
     "Test", 
     "Test", 
     "Test", 
     "Test", 
    ]; 
for ($i=0; $i<$iterations; $i++) { 
    $hash[] = $copy; 
} 
error_log("Copy: " . memory_get_usage()); 
$hash = null; 
error_log("Reset: " . memory_get_usage()); 

$hash = []; 
for ($i=0; $i<$iterations; $i++) { 
    $store = new StoreMe(); 
    $store->A = "Test"; 
    $store->B = "Test"; 
    $store->C = "Test"; 
    $store->D = "Test"; 
    $hash[] = $store; 
} 
error_log("Object: " . memory_get_usage()); 
$hash = null; 
$store = null; 
error_log("Reset: " . memory_get_usage()); 

Estos son los resultados con las imágenes Docker para PHP. El valor correcto es el consumo de memoria en bytes.

PHP 5,6

Start: 225680 
String: 8837400 
Reset: 226088 
Raw: 8837400 
Reset: 226088 
Object: 5580488 
Reset: 1209264 

PHP 7,0

Start: 355400 
String: 4643840 
Reset: 355400 
Raw: 4643840 
Reset: 355400 
Copy: 884216 
Reset: 355776 
Object: 2127096 
Reset: 478656 

PHP 7,1

Start: 355336 
String: 883776 
Reset: 355336 
Raw: 883776 
Reset: 355336 
Copy: 883776 
Reset: 355336 
Object: 2126656 
Reset: 478216 

Conclusión

Los objetos necesitan menos memoria como se esperaba. Pero PHP 5.6 parece tener problemas con la recolección de basura usando objetos. Los resultados de PHP 7.1 parecen ser algún tipo de optimización del compilador, porque no hay diferencia en "Copiar al escribir" y crear las matrices.

Cuestiones relacionadas