¿Cuál es la diferencia entre usar selfy staticen el siguiente ejemplo?
class Foo
{
protected static $bar = 1234;
public static function instance()
{
echo self::$bar;
echo "\n";
echo static::$bar;
}
}
Foo::instance();
produce
1234
1234

Respuestas:
Cuando usa
selfpara referirse a un miembro de la clase, se está refiriendo a la clase dentro de la cual usa la palabra clave. En este caso, suFooclase define una propiedad estática protegida llamada$bar. Cuando usaselfen laFooclase para hacer referencia a la propiedad, hace referencia a la misma clase.Por lo tanto, si intentó usar
self::$baren otra parte de suFooclase, pero tenía unaBarclase con un valor diferente para la propiedad, usaría enFoo::$barlugar deBar::$bar, que puede no ser lo que pretende:Cuando llamas a un método a través de
static, estás invocando una función llamada enlaces estáticos tardíos (introducidos en PHP 5.3).En el escenario anterior, el uso
selfresultará enFoo::$bar(1234). Y el usostaticresultará enBar::$bar(4321) porque constatic, el intérprete tiene en cuenta la redeclaración dentro de laBarclase durante el tiempo de ejecución.Por lo general, utiliza enlaces estáticos tardíos para métodos o incluso para la propia clase, en lugar de propiedades, ya que no suele volver a declarar propiedades en subclases; un ejemplo del uso de la
staticpalabra clave para invocar un constructor de enlace tardío se puede encontrar en esta pregunta relacionada: New self vs new staticSin embargo, eso no excluye el uso también
staticcon propiedades.fuente
<?php class Foo { public static $bar = 1234; public static function a( ) { echo 'static'.static::$bar; echo 'self'.self::$bar; } } class Bar extends Foo { public static $bar = 4321; } (new Bar())->a(); ?>self::$abccuando se usa en el interiorclass Fooes lo mismo que decirFoo::$abc. No se verá afectado por ninguna nueva declaración de$abcen una subclase. AFAIK, la única razón para usarselfes como una abreviatura, para evitar usar el nombre de la claseFoo, que puede ser más largo. [También significa que puede cambiar el nombre de la clase sin cambiar todos esos lugares, pero esa no es una gran razón en mi humilde opinión.] (La elección de nombres de PHP es desafortunada y parece al revés; "estático" es el que puede cambiar, lo cual es opuesto al significado coloquial de la palabra en lenguaje natural "estático".)Como se mencionó, una de las principales diferencias es que
staticpermite enlaces estáticos tardíos. Uno de los escenarios más útiles que encontré fue el de crear clases base para clases Singleton:El uso
return static::$nameen la clase Base devolverá lo que se adjuntó estáticamente cuando se extendió. Si se va a utilizarreturn self::$namea continuación,B::getName()se devolverá una cadena vacía, ya que es lo que se declaró en la clase base.fuente
Con
selfllamada:Puede ver arriba, aunque hemos anulado el
$varcon nuestraBarclase, todavía regresa123, porque le hemos pedido explícitamente a PHP laselfvariable, que a su vez solicitaFoola variable s en su lugar.Ahora, si intercambiamos la llamada con
static, obtendremosBarun valor anulado:Con
staticllamada:fuente