2010-03-07 12 views
80

nunca he visto como esto:¿Qué significa nuevo yo(); significa en PHP? código

public static function getInstance() 
{ 
    if (! isset(self::$_instance)) { 
     self::$_instance = new self(); 
    } 
    return self::$_instance; 
} 

¿Es lo mismo que new className()?

EDITAR

Si la clase es un heredero, que clase ¿Apunta a?

+0

http://stackoverflow.com/questions/151969/php-self-vs-this –

+0

@ stereofrog, ¿quieres decir que el patrón singleton debe abandonarse? Pero todo existe por una razón, ¿verdad? – user198729

+0

Oh, tiendo a estar de acuerdo con este punto: singleton debe ser reemplazado por fábrica – user198729

Respuesta

164

self apunta a la clase en la que está escrito.

tanto, si su método getInstance está en un nombre de clase MyClass, la siguiente línea:

self::$_instance = new self(); 

va a hacer lo mismo que:

self::$_instance = new MyClass(); 



Editar: un par de informaciones más, después de la comunicación ents.

Si tiene dos clases que se extienden entre sí, que tienen dos situaciones:

  • getInstance se define en la clase hija
  • getInstance se define en la clase padre

El La primera situación se vería así (he eliminado todo el código no necesario, para este ejemplo, tendrás que volver a agregarlo para obtener el comportamiento singleton) *:

class MyParentClass { 

} 
class MyChildClass extends MyParentClass { 
    public static function getInstance() { 
     return new self(); 
    } 
} 

$a = MyChildClass::getInstance(); 
var_dump($a); 

Aquí, usted obtendrá:

object(MyChildClass)#1 (0) { } 

Lo que significa self significa MyChildClass - es decir, la clase en la que está escrito.


Para la segunda situación, el código se vería así:

class MyParentClass { 
    public static function getInstance() { 
     return new self(); 
    } 
} 
class MyChildClass extends MyParentClass { 

} 

$a = MyChildClass::getInstance(); 
var_dump($a); 

y que le obtener este tipo de salida:

object(MyParentClass)#1 (0) { } 

Lo que significa self significa MyParentClass - es decir, aquí también, la clase en la que está escrito.




Con PHP < 5.3, que "la clase en la que está escrito" es importante - y, a veces puede causar problemas.

Por eso PHP 5.3 introduce un nuevo uso de la palabra clave static: ahora se puede utilizar exactamente donde se utilizó self en estos ejemplos:

class MyParentClass { 
    public static function getInstance() { 
     return new static(); 
    } 
} 
class MyChildClass extends MyParentClass { 

} 

$a = MyChildClass::getInstance(); 
var_dump($a); 

Pero, con static en lugar de self, podrás ahora llegar:

object(MyChildClass)#1 (0) { } 

lo que significa que static tipo de puntos de la clase que se utiliza (que utiliza MyChildClass::getInstance()), y no aquel en el que está escrito.

Por supuesto, el comportamiento de self no se ha modificado para no interrumpir las aplicaciones existentes: PHP 5.3 acaba de agregar un nuevo comportamiento, reciclando la palabra clave static.


Y, hablando de PHP 5.3, es posible que desee echar un vistazo a la página Late Static Bindings del manual de PHP.

+1

+1, pero creo que quiso decir "denota" en lugar de "diseños"? –

+0

@Paul: heu ... significaba que "el self actúa como un alias", o "self sort of points to" - el verbo "designer", en francés, puede usarse para eso - supongo que ese es uno de los situaciones en las que usar la misma palabra en inglés no es una buena idea ;-(Editaré mi respuesta para arreglar esto ;; gracias :-) –

+0

¿Qué pasa si hay 'baseclass',' class', cuál lo hace señalar ¿a? – user198729

1

Sí, es como new className() (refiriéndose a la clase que contiene ese método), probablemente utilizado en un patrón de Singleton donde el constructor es privado.

+0

¡El constructor Exactamente! es privado! – user198729

+0

¿Por qué alguien usaría el patrón de Singleton en PHP? A menos que se use en un programa similar a un daemon, el singleton solo vivirá mientras el script se ejecuta y luego desaparecerá junto con el programa. – ILikeTacos

+2

para evitar declarar irritantemente global para acceder a una variable global –

9

Esto parece ser una implementación de Singleton pattern. La función se llama estáticamente y verifica si la clase estática tiene la variable $_instance establecida.

Si no lo está, inicializa una instancia de sí mismo (new self()) y lo almacena en $_instance.

Si llama al className::getInstance() obtendrá la misma instancia de clase en cada llamada, que es el punto del patrón singleton.

Nunca lo he visto así hecho de esta manera, y sinceramente no sabía que era posible. ¿Qué es $_instance declarado como en la clase?

+1

'$ _instance' se declara como' public static $ _instance; ' – Atif

6

Esto se usa muy probablemente en el patrón de diseño singleton, donde el constructor se define como privado para evitar la creación de instancias, el operador double colon (::) puede acceder a miembros que están declarados estáticos dentro de la clase, por lo que , la pseudovariable $ this no se puede usar, de ahí que el código use self, Singletons son buenas prácticas de programación que solo permitirán 1 instancia de un objeto como manejadores de conector de base de datos. Desde el código del cliente, acceder a esa instancia se haría creando un solo punto de acceso, en este caso lo llamó getInstance(), la getInstance en sí misma fue la función que creó el objeto básicamente usando la palabra clave new para crear un objeto que significa el método constructor también fue llamado.

la línea if(!isset(self::instance)) comprueba si ya se ha creado un objeto, que no podían entender este becuase el código es sólo un fragmento, en algún lugar de la parte superior, no debe haber miembros estáticos como probablemente

private static $_instance = NULL; 

en condiciones normales clases que hubieran accedido a este miembro simplemente

$this->_instance = 'something'; 

pero su declarada estática y por lo que no podrían usar el $ el código que utilizamos en lugar

self::$_instance 

comprobando si hay un objeto almacenado en esta variable de clase estática, la clase puede decidir crear o no crear una sola instancia, por lo que si no está establecida,! Isset, lo que significa que no existe ningún objeto en el miembro estático $ _instance, entonces se genera un nuevo objeto, almacenada en el miembro estático $_instance por el comando

self::$_instance = new self(); 

y lo devolvió al código de cliente. El código del cliente puede utilizar felizmente la única instancia del objeto con sus métodos públicos, pero en el código del cliente, llamando al único punto de acceso, es decir, el método getInstance() también es complicado, debe llamarse así

$thisObject = className::getInstance(); 

el motivo, la función en sí misma se declara estática.

0

Si la clase se hereda, al llamar a getInstance() desde el niño no se le dará una instancia de niño. Solo devolverá una instancia de instancia principal. Esto se debe a que llamamos nuevo yo().

Si desea que la clase secundaria devuelva una instancia de clase secundaria, utilice nueva static() en getInstance() y luego devolverá la instancia de clase secundaria. ¡Esto se llama enlace tardío!