2010-02-04 22 views
111

¿cómo puedo llamar a un método estático desde otro método dentro de la misma clase?llamar a un método estático dentro de una clase?

$this->staticMethod(); 

o

$this::staticMethod(); 
+11

Usted puede estar interesado en este ('' self' vs. $ this') : http://stackoverflow.com/questions/151969/php-self-vs-this –

+0

Solo un FYI, 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

+0

puede eliminar el $ this ahora, por favor, no funciona si solo utiliza métodos estáticos y no existe ninguna instancia. – malhal

Respuesta

211
+0

... pero ¿por qué? $ this-> staticMethod() también funciona. ¿Puedes explicar por qué self :: staticMethod() es más correcto (si lo es)? –

+15

@ Ian Dunn En pocas palabras, '$ this' solo existe si un objeto ha sido instanciado y solo puede usar' $ this-> method' desde dentro de 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 usar 'self ::'. Para evitar posibles errores (y advertencias estrictas), es mejor usar 'self'. – jeroen

+0

No puede usar $ this en una función estática .... – patrick

36

Vamos a suponer que este es su clase:

class Test 
{ 
    private $baz = 1; 

    public function foo() { ... } 

    public function bar() 
    { 
     printf("baz = %d\n", $this->baz); 
    } 

    public static function staticMethod() { echo "static method\n"; } 
} 

desde el Método foo(), vamos a ver las diferentes opciones:

$this->staticMethod(); 

Así que llama a staticMethod() como método de instancia, ¿verdad? No es asi. Esto es porque el método se declara como public static, el intérprete lo llamará como un método estático, por lo que funcionará como se esperaba. Se podría argumentar que hacerlo hace que sea menos obvio por el código que se está llevando a cabo una llamada al método estático.

$this::staticMethod(); 

A partir de PHP 5.3 se puede utilizar para referirse a $var::method()<class-of-$var>::; esto es bastante conveniente, aunque el caso de uso anterior todavía es bastante poco convencional. Esto nos lleva a la forma más común de llamar a un método estático:

self::staticMethod(); 

Ahora, antes de empezar a pensar que el :: es el operador de llamada estática, te voy a dar otro ejemplo:

self::bar(); 

Esto imprimirá baz = 1, lo que significa que $this->bar() y self::bar() hacen exactamente lo mismo; eso es porque :: es solo un operador de resolución de alcance. Está ahí para hacer que parent::, self:: y static:: funcionen y le den acceso a variables estáticas; cómo se llama un método depende de su firma y de cómo se llamó a la persona que llama.

Para ver todo esto en acción, consulte this 3v4l.org output.

+6

+1 para la explicación – FreshPro

+0

'self :: bar()' parece engañoso - ¿está ahora en desuso? (usando 'self ::' para llamar a un método de instancia en lugar de un método estático). – ToolmakerSteve

+0

@ToolmakerSteve ¿de qué manera dirías que es engañoso? –

7

Esta es una respuesta muy tardía, pero las dos respuestas anteriores son un poco engañosas.

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 clase.

Tomemos por ejemplo este código:

class static_test_class { 
    public static function test() { 
     echo "Original class\n"; 
    } 

    public static function run($use_self) { 
     if($use_self) { 
      self::test(); 
     } else { 
      $class = get_called_class(); 
      $class::test(); 
     } 
    } 
} 

class extended_static_test_class extends static_test_class { 
    public static function test() { 
     echo "Extended class\n"; 
    } 
} 

extended_static_test_class::run(true); 
extended_static_test_class::run(false); 

La salida de este código es:

clase original

clase extendida

Esto se debe a self se refiere a la clase en la que se encuentra el código, en lugar de la c del código desde el que se está llamando.

Si desea utilizar un método definido en una clase que hereda la clase original, es necesario utilizar algo como:

$class = get_called_class(); 
$class::function_name(); 
+2

Encontré este informativo. Una pequeña queja, no diría que las otras respuestas son "engañosas". Más exacto decir que están "incompletos"; no abordan la pregunta (sin responder) de lo que hace 'self ::' en el (raro) caso en 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étodo 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 anule los métodos de instancia (que es la esencia de la codificación OO), pero no de 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 "self" no se usaría en ese caso. Has declarado una clase separada como una extensión a la primera clase. Usar 'self' 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 del "yo". – iyrin

1

En la posterior versión de PHP self::staticMethod(); tampoco va a funcionar. Arrojará el estricto error estándar.

En este caso, se puede crear el objeto de la misma clase y llamar por objeto

aquí es el ejemplo

class Foo { 

    public function fun1() { 
     echo 'non-static'; 
    } 

    public static function fun2() { 
     echo (new self)->fun1(); 
    } 
} 
+0

Gran entrada, gracias – Joundill

Cuestiones relacionadas