Pregunta

A continuación se muestra un ejemplo de jerarquía de clases y código.Lo que estoy buscando es una manera de determinar si 'ChildClass1' o 'ChildClass2' tenían el método estático whoAmI() llamado sin volver a implementarlo en cada clase secundaria.

<?php

abstract class ParentClass {

    public static function whoAmI () {

        // NOT correct, always gives 'ParentClass'
        $class = __CLASS__;

        // NOT correct, always gives 'ParentClass'. 
        // Also very round-about and likely slow.
        $trace = debug_backtrace();
        $class = $trace[0]['class'];

        return $class;
    }
}

class ChildClass1 extends ParentClass {

}

class ChildClass2 extends ParentClass {

}

// Shows 'ParentClass'
// Want to show 'ChildClass1'
print ChildClass1::whoAmI(); 
print "\n";

// Shows 'ParentClass'
// Want to show 'ChildClass2'
print ChildClass2::whoAmI();
print "\n";
¿Fue útil?

Solución 3

Ahora que PHP 5.3 está ampliamente disponible, quería elaborar una respuesta resumida a esta pregunta para reflejar las nuevas técnicas disponibles.

Como se menciona en las otras respuestas, PHP 5.3 ha introducido Enlace estático tardío a través de un nuevo static palabra clave.Así mismo, un nuevo get_called_class() La función también está disponible y solo se puede usar dentro de un método de clase (de instancia o estático).

A los efectos de determinar la clase como se preguntó en esta pregunta, el get_called_class() la función es apropiada:

<?php

abstract class ParentClass {

    public static function whoAmI () {
        return get_called_class();
    }

}

class ChildClass1 extends ParentClass {

}

class ChildClass2 extends ParentClass {

}

// Shows 'ChildClass1'
print ChildClass1::whoAmI(); 
print "\n";

// Shows 'ChildClass2'
print ChildClass2::whoAmI();
print "\n";

El notas aportadas por el usuario para get_called_class() incluya algunas implementaciones de muestra que deberían funcionar también en PHP 5.2 haciendo uso de debug_backtrace().

Otros consejos

Creo que te refieres a un error conocido de PHP.Php 5.3 tiene como objetivo abordar este problema con una nueva función de enlace estático tardío.

http://www.colder.ch/news/08-24-2007/28/late-static-bindings-expl.html

La identificación de clase es a menudo un síntoma de polimorfismo no bien comprendido.

Los clientes de ChildClass1 y ChildClass2 no deberían necesitar distinguir entre ellos.

No hay ningún lugar donde cualquier clase deba preguntar sobre someObject.whoAmI().

Siempre que tengas ganas de escribir if someObject.whoAmI() == 'ChildClass1' { do X(someObject) } realmente deberías agregar un X() método para ParentClass con varias implementaciones en las distintas ChildClasses.

Este tipo de "identificación de tipo en tiempo de ejecución" casi siempre se puede reemplazar con diseños de clases adecuadamente polimórficos.

A partir de PHP 5.3 será posible con el uso del palabra clave estática, pero por ahora no es posible.

No.Espere a PHP 5.3.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top