Domanda

Di seguito è riportato un esempio di gerarchia di classi e codice.Quello che sto cercando è un modo per determinare se "ChildClass1" o "ChildClass2" aveva il metodo statico whoAmI() chiamato su di esso senza reimplementarlo in ogni classe figlia.

<?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";
È stato utile?

Soluzione 3

Ora che PHP 5.3 è ampiamente disponibile, ho voluto mettere insieme una risposta riassuntiva a questa domanda per riflettere le nuove tecniche disponibili.

Come accennato nelle altre risposte, PHP 5.3 ha introdotto Legame statico tardivo tramite un nuovo static parola chiave.Inoltre, un nuovo get_called_class() è disponibile anche una funzione che può essere utilizzata solo all'interno di un metodo di classe (istanza o statico).

Allo scopo di determinare la classe come è stato chiesto in questa domanda, il get_called_class() la funzione è appropriata:

<?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";

IL note fornite dall'utente per get_called_class() includere alcune implementazioni di esempio che dovrebbero funzionare anche in PHP 5.2 utilizzando debug_backtrace().

Altri suggerimenti

Credo che quello a cui ti riferisci sia un noto bug di php.Php 5.3 mira a risolvere questo problema con una nuova funzionalità di associazione tardiva statica.

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

L'identificazione della classe è spesso un sintomo di polimorfismo non ben compreso.

I client di ChildClass1 e ChildClass2 non dovrebbero aver bisogno di distinguerli.

Non c'è nessun posto dove una classe dovrebbe chiedere informazioni someObject.whoAmI().

Ogni volta che hai voglia di scrivere if someObject.whoAmI() == 'ChildClass1' { do X(someObject) } dovresti davvero aggiungere un X() metodo alla ParentClass con varie implementazioni nelle varie ChildClasses.

Questo tipo di "identificazione del tipo in fase di esecuzione" può quasi sempre essere sostituito con progetti di classi adeguatamente polimorfici.

A partire da PHP 5.3 sarà possibile con l'uso del file parola chiave statica, ma per ora non è possibile.

NO.Attendi PHP 5.3.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top