Llamar a un método no estático con dos puntos (::)

Resuelto Jfish033 asked hace 54 años • 0 respuestas

¿Por qué no puedo utilizar un método no estático con la sintaxis de los métodos static(class::method) ? ¿Es algún tipo de problema de configuración?

class Teste {

    public function fun1() {
        echo 'fun1';
    }
    public static function fun2() {
        echo "static fun2" ;
    }
}

Teste::fun1(); // why?
Teste::fun2(); //ok - is a static method
Jfish033 avatar Jan 01 '70 08:01 Jfish033
Aceptado

PHP es muy flexible con métodos estáticos y no estáticos. Una cosa que no veo aquí es que si llamas a un método no estático, nsestáticamente desde dentro de un método no estático de clase C, $thisel interior nsse referirá a tu instancia de C.

class A 
{
    public function test()
    {
        echo $this->name;
    }
}

class C 
{
     public function q()
     {
         $this->name = 'hello';
         A::test();
     }
}

$c = new C;
$c->q();// prints hello

En realidad, esto es un error de algún tipo si tiene un informe de errores estricto, pero no en caso contrario.

davidtbernal avatar Sep 20 '2010 20:09 davidtbernal

Esta es una "peculiaridad" conocida de PHP. Está diseñado para evitar la propagación hacia atrás para determinar si hace algún tiempo realmente creamos una instancia de un objeto o no (recuerde, PHP se interpreta, no se compila). Sin embargo, acceder a cualquier miembro no estático mediante el operador de resolución de alcance si no se crea una instancia del objeto generará un error fatal.

Cortesía de PHP.net:

class User {
    const GIVEN = 1;  // class constants can't be labeled static nor assigned visibility
    public $a=2;
    public static $b=3;

    public function me(){
        echo "print me";
    }
     public static function you() {
        echo "print you";
    }
}

class myUser extends User {
}

// Are properties and methods instantiated to an object of a class, & are they accessible?
//$object1= new User();        // uncomment this line with each of the following lines individually
//echo $object1->GIVEN . "</br>";        // yields nothing
//echo $object1->GIVE . "</br>";        //  deliberately misnamed, still yields nothing
//echo $object1->User::GIVEN . "</br>";    // yields nothing
//echo $object1->a . "</br>";        // yields 2
//echo $object1->b . "</br>";        // yields nothing
//echo $object1->me() . "</br>";        // yields print me
//echo $object1->you() . "</br>";        // yields print you

// Are  properties and methods instantiated to an object of a child class,  & are accessible?
//$object2= new myUser();        // uncomment this line with each of the following lines individually
//echo $object2->GIVEN . "</br>";        // yields nothing
//echo $object2->a . "</br>";        // yields 2
//echo $object2->b . "</br>";        // yields nothing
//echo $object2->me() . "</br>";        // yields print me
//echo $object2->you() . "</br>";        // yields print you

// Are the properties and methods accessible directly in the class?
//echo User::GIVEN . "</br>";        // yields 1
//echo User::$a . "</br>";            // yields fatal error since it is not static
//echo User::$b . "</br>";            // yields 3
//echo User::me() . "</br>";        // yields print me
//echo User::you() . "</br>";        // yields print you

// Are the properties and methods copied to the child class and are they accessible?
//echo myUser::GIVEN . "</br>";        // yields 1
//echo myUser::$a . "</br>";        // yields fatal error since it is not static
//echo myUser::$b . "</br>";        // yields 3
//echo myUser::me() . "</br>";        // yields print me
//echo myUser::you() . "</br>";        // yields print you
?>
David Titarenco avatar Sep 20 '2010 19:09 David Titarenco

Esta es la compatibilidad con versiones anteriores de PHP 4. En PHP 4 no se podía diferenciar entre un método de objeto y la función global escrita como un método de clase estática. Por lo tanto, ambos funcionaron.

Sin embargo, con los cambios en el modelo de objetos con PHP 5 ( http://php.net/oop5 ), se introdujo la palabra clave estática.

Y luego, desde PHP 5.1.3, obtienes advertencias estándar estrictas y adecuadas sobre temas como:

Estándares estrictos: el método no estático Foo::bar() no debe llamarse estáticamente

Y/O:

Estándares estrictos: el método no estático Foo::bar() no debe llamarse estáticamente, suponiendo que $this proviene de un contexto incompatible

que debería haber habilitado para su configuración de desarrollo. Por lo tanto, es simplemente compatibilidad con versiones anteriores de una época en la que el lenguaje no podía diferir lo suficiente, por lo que esto se "definió" en tiempo de ejecución.

Hoy en día ya puedes definirlo en el código, sin embargo, el código no se romperá si aún lo llamas "incorrecto".

Algunas demostraciones para activar los mensajes de error y mostrar el comportamiento modificado en diferentes versiones de PHP: http://3v4l.org/8WRQH

hakre avatar Sep 09 '2013 09:09 hakre

Puede hacer esto, pero su código generará un error si usa $thisla función llamadafun1()

Jake N avatar Sep 20 '2010 19:09 Jake N

Advertencia En PHP 7, llamar estáticamente a métodos no estáticos está en desuso y generará una advertencia E_DEPRECATED. Es posible que en el futuro se elimine la compatibilidad con la llamada estática a métodos no estáticos.

Enlace

Malus Jan avatar Oct 27 '2017 14:10 Malus Jan