Solo para su información, su primer ejemplo es una variable de instancia que llama a un método estático que no es posible porque un método estático es parte de la clase y no es accesible a través de una variable de instancia.
joejoeson
puede eliminar $ this ahora, por favor, no funciona si solo usa métodos estáticos y no existe una instancia.
...¿pero por qué? $ this-> staticMethod () también funciona. ¿Puedes explicar por qué self :: staticMethod () es más correcto (si lo es)?
Ian Dunn
29
@Ian Dunn En pocas palabras, $thissolo existe si se ha instanciado un objeto y solo se puede usar $this->methoddesde un objeto existente. Si no tiene ningún objeto pero solo llama a un método estático y en ese método desea llamar a otro método estático en la misma clase, debe usarlo self::. Por lo tanto, para evitar posibles errores (y advertencias estrictas) es mejor usarlo self.
jeroen
1
¡Gracias! En laravel, descubrí que accidentalmente estaba llamando al método estático a través de un controlador extendido usando $this, pero el problema no surgió hasta que se introdujo el código stage. no volvieron errores, el valor era justo 0. tenga cuidado con esto, useself::
Desde dentro del foo()método, veamos las diferentes opciones:
$this->staticMethod();
Entonces eso llama staticMethod()como un método de instancia, ¿verdad? No es asi. Esto se debe a que el método se declara ya que public staticel intérprete lo llamará como método estático, por lo que funcionará como se esperaba. Podría argumentarse que al hacerlo, resulta menos obvio del código que se está realizando una llamada al método estático.
$this::staticMethod();
Desde PHP 5.3 puede usar $var::method()para significar <class-of-$var>::; Esto es bastante conveniente, aunque el caso de uso anterior todavía es poco convencional. Eso nos lleva a la forma más común de llamar a un método estático:
self::staticMethod();
Ahora, antes de comenzar a pensar que ::es el operador de llamada estática, déjame darte otro ejemplo:
self::bar();
Esto imprimirá baz = 1, lo que significa eso $this->bar()y self::bar()hará exactamente lo mismo; eso es porque ::es solo un operador de resolución de alcance. Es ahí para hacer parent::, self::y static::el trabajo y dará acceso a las variables estáticas; cómo se llama a un método depende de su firma y cómo se llamó a la persona que llama.
self::bar()parece engañoso, ¿está ahora en desuso? (utilizando self::para llamar a un método de instancia en lugar de un método estático).
ToolmakerSteve
@ToolmakerSteve, ¿de qué manera dirías que es engañoso?
Ja͢ck
Lógicamente hablando, no existe selfcuando se invoca un método estático. Por definición: el método estático se puede llamar desde cualquier lugar y no recibe un parámetro "propio". Sin embargo, veo la conveniencia de esa phpsintaxis, para que no tenga que escribir MyClassName::. Estoy acostumbrado a los lenguajes de tipo estático, donde el compilador tiene que recibir todas las variables disponibles en el ámbito actual, por lo que (el equivalente de) self::puede omitirse. Entonces uno solo dijo self instanceMethod; No hay razón para decir self staticMethod.
ToolmakerSteve
15
Esta es una respuesta muy tardía, pero agrega algunos detalles sobre las respuestas anteriores.
Cuando se trata de llamar a métodos estáticos en PHP desde otro método estático en la misma clase, es importante diferenciar entre selfy el nombre de la clase.
Encontré esto informativo. Una pequeña mentira, no diría que las otras respuestas son "engañosas". Más exacto decir que están "incompletos"; no abordan la pregunta (no formulada) de qué self::sucede en el caso (raro) en el que un método estático A llama a otro método estático B, y B ha sido anulado en una subclase. En mi humilde opinión, es menos confuso restringir la anulación de métodos a métodos de "instancia"; usa esa habilidad con moderación en el nivel estático. Dicho de otra manera, los lectores de su código esperan que el método sobrescriba los métodos de instancia (esa es la esencia de la codificación OO), pero no los estáticos.
ToolmakerSteve
1
Muy útil y tiene sentido que una extensión de la clase no sea la clase original. Por lo tanto, es lógico pensar que selfno se utilizaría en ese caso. Has declarado una clase separada como una extensión de la primera clase. Usar selfdentro de la clase extendida se referiría a la clase extendida. Esto no contradice las otras respuestas, pero ciertamente ayuda a demostrar el alcance de self.
iyrin
2
En la versión posterior de PHP self::staticMethod();tampoco funcionará. Lanzará el estricto error estándar.
En este caso, podemos crear objetos de la misma clase y llamar por objeto
Usted podría hacer eso, aunque si fun1no se está haciendo uso de self, no es lógico que sea un método de instancia. La forma correcta de hacer esto en php es declarar public static function fun1, a continuación, llamar mediante la especificación de la clase: Foo::fun1. Estoy seguro de que esa es la forma prevista para corregir ese error estándar estricto.
self
vs.$this
): stackoverflow.com/questions/151969/php-self-vs-thisRespuestas:
Más información sobre la palabra clave estática.
fuente
$this
solo existe si se ha instanciado un objeto y solo se puede usar$this->method
desde un objeto existente. Si no tiene ningún objeto pero solo llama a un método estático y en ese método desea llamar a otro método estático en la misma clase, debe usarloself::
. Por lo tanto, para evitar posibles errores (y advertencias estrictas) es mejor usarloself
.$this
, pero el problema no surgió hasta que se introdujo el códigostage
. no volvieron errores, el valor era justo0
. tenga cuidado con esto, useself::
Asumamos que esta es tu clase:
Desde dentro del
foo()
método, veamos las diferentes opciones:Entonces eso llama
staticMethod()
como un método de instancia, ¿verdad? No es asi. Esto se debe a que el método se declara ya quepublic static
el intérprete lo llamará como método estático, por lo que funcionará como se esperaba. Podría argumentarse que al hacerlo, resulta menos obvio del código que se está realizando una llamada al método estático.Desde PHP 5.3 puede usar
$var::method()
para significar<class-of-$var>::
; Esto es bastante conveniente, aunque el caso de uso anterior todavía es poco convencional. Eso nos lleva a la forma más común de llamar a un método estático:Ahora, antes de comenzar a pensar que
::
es el operador de llamada estática, déjame darte otro ejemplo:Esto imprimirá
baz = 1
, lo que significa eso$this->bar()
yself::bar()
hará exactamente lo mismo; eso es porque::
es solo un operador de resolución de alcance. Es ahí para hacerparent::
,self::
ystatic::
el trabajo y dará acceso a las variables estáticas; cómo se llama a un método depende de su firma y cómo se llamó a la persona que llama.Para ver todo esto en acción, vea este resultado de 3v4l.org .
fuente
self::bar()
parece engañoso, ¿está ahora en desuso? (utilizandoself::
para llamar a un método de instancia en lugar de un método estático).self
cuando se invoca un método estático. Por definición: el método estático se puede llamar desde cualquier lugar y no recibe un parámetro "propio". Sin embargo, veo la conveniencia de esaphp
sintaxis, para que no tenga que escribirMyClassName::
. Estoy acostumbrado a los lenguajes de tipo estático, donde el compilador tiene que recibir todas las variables disponibles en el ámbito actual, por lo que (el equivalente de)self::
puede omitirse. Entonces uno solo dijoself instanceMethod
; No hay razón para decirself staticMethod
.Esta es una respuesta muy tardía, pero agrega algunos detalles sobre las respuestas anteriores.
Cuando se trata de llamar a métodos estáticos en PHP desde otro método estático en la misma clase, es importante diferenciar entre
self
y el nombre de la clase.Tome por ejemplo este código:
La salida de este código es:
Esto se debe a que se
self
refiere a la clase en la que se encuentra el código, en lugar de la clase del código desde el que se llama.Si desea usar un método definido en una clase que hereda la clase original, debe usar algo como:
fuente
self::
sucede en el caso (raro) en el que un método estático A llama a otro método estático B, y B ha sido anulado en una subclase. En mi humilde opinión, es menos confuso restringir la anulación de métodos a métodos de "instancia"; usa esa habilidad con moderación en el nivel estático. Dicho de otra manera, los lectores de su código esperan que el método sobrescriba los métodos de instancia (esa es la esencia de la codificación OO), pero no los estáticos.self
no se utilizaría en ese caso. Has declarado una clase separada como una extensión de la primera clase. Usarself
dentro de la clase extendida se referiría a la clase extendida. Esto no contradice las otras respuestas, pero ciertamente ayuda a demostrar el alcance deself
.En la versión posterior de PHP
self::staticMethod();
tampoco funcionará. Lanzará el estricto error estándar.En este caso, podemos crear objetos de la misma clase y llamar por objeto
aquí está el ejemplo
fuente
fun1
no se está haciendo uso deself
, no es lógico que sea un método de instancia. La forma correcta de hacer esto en php es declararpublic static function fun1
, a continuación, llamar mediante la especificación de la clase:Foo::fun1
. Estoy seguro de que esa es la forma prevista para corregir ese error estándar estricto.