2010-02-05 23 views
19

no soy un programador de PHP (pero conocen otros idiomas), y estoy tratando de entender una página web que se ha hecho en PHP (5.1.6) con el fin de hacer algunos cambios.PHP "y" operador

la página tiene el siguiente código (simplificado):

$db_hosts = array(); 
$sql = 'SELECT h.hostid, h.host FROM hosts h '; 

$db_items = DBselect($sql); 

while($db_item = DBfetch($db_items)){ 
    $name = $db_item['host']; 
    $db_host = &$db_hosts[$db_item['hostid']]; 
} 

Estoy tratando de comprender la última línea, $db_host = &$db_hosts[$db_item['hostid']];.

Parece que está creando una nueva variable, $db_host, y poniendo algo dentro de ella, pero no entiendo &$db_hosts.

estoy en duda porque por lo que yo sé, $db_hosts es una matriz vacía.

He encontrado this y this, pero no estoy muy seguro, ya que en estos enlaces, el operador es "= &", y en el código, el operador está unido a la variable "= & $ db_hosts" (tiene un espacio entre = y &).

Desde traté de modificarlo y no conseguir el éxito, pensé que era mejor pedir ayuda ...

Respuesta

25

Esas son las referencias, y son similares a "punteros" en C o C++.

Más información se encuentra en la PHP manual.

En este caso, puesto que $db_hosts está vacía, el constructo $db_hosts[$db_item['hostid']] va a crear una nueva matriz con un elemento vacío en el índice de $db_item['hostid'] y devolver la referencia del artículo, haciendo $db_host actuar como un 'alias' para lo $db_hosts[$db_item['hostid']] es actualmente.

+0

Esto es correcto. Estaba haciendo demasiadas cosas a la vez y respondí muy rápido :-) – Josh

+6

Y, como estamos discutiendo las referencias de PHP, un enlace al post titulado "No utilizar referencias PHP" está en orden - http://schlueters.de/ blog/archives/125-Do-not-use-PHP-references.html –

+2

Un poco de corrección ... en realidad no son como Punteros en C .. http://www.php.net/manual/en/language. references.arent.php –

1

El & se utiliza para obtener una referencia a una variable. Es similar a las referencias en otros lenguajes como C++, con algunas diferencias significativas. Vea el PHP Manual's section on references.

+0

Su pensamiento del símbolo @. – rook

+1

@Michael Brooks: sí, lo sentí, lo siento, respondí demasiado rápido. He corregido mi respuesta. – Josh

+3

Si bien parece razonable a primera vista, esta es una respuesta muy engañosa: el '&' no "obtiene" una referencia, porque la referencia en sí no tiene existencia (como, por ejemplo, un puntero C). En cambio, es mejor pensar en '= &' como un operador que vincula dos variables juntas, y la sintaxis relacionada, como 'function foo (& $ bar)', como formas de escribir esa asignación. – IMSoP

2

& se utiliza como una referencia. Vea lo que las referencias están en http://php.net/manual/en/language.references.php:

Referencias en PHP son un medio para acceder al mismo contenido variable nombres diferentes. No son como punteros C ; por ejemplo, no puede realizar aritmética de puntero con ellos, no son direcciones de memoria reales, y así sucesivamente.

4

La asignación de esa variable como referencia lo hace de modo que si posteriormente se cambia $ db_host, también cambiará la entrada correspondiente en la matriz $ db_hosts, y viceversa.

he visto una buena cantidad de uso bastante inútil de referencias en PHP, estilo culto cargo. Tal vez sea necesario, tal vez no; tendrías que mirar el resto del programa.

9

& se usa de varias formas en PHP para denotar referencias (see this manual section), pero es engañoso pensar que es un operador en sí mismo. Es por eso que algunas personas prefieren escribir $foo =& $bar en lugar de $foo = &$bar - significa lo mismo, pero enfatiza que la "referencia-y-ness" es una propiedad de la asignación, no de las variables.

En algunos lenguajes de programación, como C o C++, puede "obtener una referencia" a una variable en particular; el valor resultante puede pasarse como una entidad distinta y luego "desreferenciarse" para descubrir dónde apunta. Esto es no qué referencias de PHP son.

En su lugar, todos Las variables PHP son en realidad referencias a un tipo interno llamado zval. No se puede manipular directamente zval s en PHP, y tampoco se pueden crear capas adicionales de direccionamiento indirecto: cada variable es una referencia a zval, y eso es todo. (Ver advertencia: los objetos más abajo.)

Lo que una asignación por referencia ($foo =& $bar), una referencia pase por (function foo(&$bar) { ... }), o una referencia de devolución por (return &$foo) hacer es decirle a PHP que desea dos variables para apuntar al mismo zval. Tenga en cuenta que no está señalando una variable "en" otro - ambos son igualmente "reales", y llamando al unset() en cualquiera de los dos dejará el otro completamente intacto.

Advertencia: Objetos

A menudo se dice que engañosamente ya que los objetos de PHP5 son "siempre pasa por referencia". La verdad es que tienen una capa adicional de direccionamiento indirecto, donde el zval es en sí mismo un puntero a un objeto particular. Esto nos da tres cosas diferentes que podemos hacer referencia a: la variable , la zval apunta a, y la objeto que que apunta a:

// Create an object, and point three variables at it in different ways: 
$foo = new stdClass; 
$bar_by_value = $foo; 
$bar_by_ref =& $foo; 

// Change the object: updates the object shared by all three variables 
$foo->value = 42; 
// Change the value (zval) of $foo: will update $bar_by_ref, 
// but $bar_by_value still points at the original object 
$foo = 42; 
// Change the variable itself: will never affect $bar_by_value or $bar_by_ref 
unset($foo); 
6

Pregunta:

¿Qué significa " & "significa aquí en PHP?

PHP "&" operador

hace la vida más fácil una vez que nos acostumbramos a ella .. (comprobar ejemplo a continuación cuidadosamente)

& normalmente comprueba bits que están activos en tanto $ a y $ b están establecidos.

¿Ha notado cómo funcionan estas llamadas?

error_reporting(E_ERROR | E_WARNING | E_PARSE); 
    error_reporting(E_ERROR | E_WARNING | E_PARSE | E_NOTICE); 
    error_reporting(E_ALL & ~E_NOTICE); 
    error_reporting(E_ALL); 

Así que detrás de todo lo anterior es el juego del operador de bits y los bits.

Un caso útil de estos es configuraciones fáciles de usar como dar a continuación, por lo que un solo campo entero puede almacenar miles de combinaciones para usted.

La mayoría de las personas ya han leído los documentos pero no han confirmado el caso de uso real de estos operadores bit a bit.

Ejemplo Eso puede ser muy útil cotidiana php vida

<?php 

class Config { 

    // our constants must be 1,2,4,8,16,32,64 ....so on 
    const TYPE_CAT=1; 
    const TYPE_DOG=2; 
    const TYPE_LION=4; 
    const TYPE_RAT=8; 
    const TYPE_BIRD=16; 
    const TYPE_ALL=31; 

    private $config; 

    public function __construct($config){ 
     $this->config=$config; 

     if($this->is(Config::TYPE_CAT)){ 
      echo 'cat '; 
     } 
     if($this->is(Config::TYPE_DOG)){ 
      echo 'dog '; 
     } 
     if($this->is(Config::TYPE_RAT)){ 
      echo 'rat '; 
     } 
     if($this->is(Config::TYPE_LION)){ 
      echo 'lion '; 
     } 
     if($this->is(Config::TYPE_BIRD)){ 
      echo 'bird '; 
     } 
     echo "\n"; 
    } 

    private function is($value){ 
     return $this->config & $value; 
    } 
} 

new Config(Config::TYPE_ALL); 
// cat dog rat lion bird 
new Config(Config::TYPE_BIRD); 
//bird 
new Config(Config::TYPE_BIRD | Config::TYPE_DOG); 
//dog bird 
new Config(Config::TYPE_ALL & ~Config::TYPE_DOG & ~Config::TYPE_CAT); 
//rat lion bird 
+1

Este es un gran ejemplo ... de un operador completamente diferente. También se escribe '&', pero el operador en la pregunta es * una asignación por referencia *, y nada que ver con las operaciones bit a bit. – IMSoP