Есть ли способ обнаружить целевой класс в статических методах? - PullRequest
1 голос
/ 17 сентября 2008

Ниже приведен пример иерархии классов и кода. То, что я ищу, - это способ определить, вызывал ли статический метод whoAmI () для ChildClass1 или ChildClass2 его вызов без повторной реализации в каждом дочернем классе.

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

Ответы [ 5 ]

7 голосов
/ 17 сентября 2008

Я полагаю, что вы имеете в виду известную ошибку php. Php 5.3 направлен на решение этой проблемы с помощью новой функции позднего статического связывания.

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

2 голосов
/ 06 сентября 2009

Теперь, когда PHP 5.3 широко доступен в дикой природе, я хотел собрать краткий ответ на этот вопрос, чтобы отразить новые доступные методы.

Как упоминалось в других ответах, в PHP 5.3 введено Позднее статическое связывание через новое ключевое слово static. Также доступна новая функция get_called_class(), которую можно использовать только в методе класса (экземпляре или статическом).

Для определения класса, как было задано в этом вопросе, подходит функция get_called_class():

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

Пользовательские примечания для get_called_class() включают несколько примеров реализаций, которые также должны работать в PHP 5.2 с использованием debug_backtrace().

2 голосов
/ 21 сентября 2008

Идентификация класса часто является симптомом недостаточно понятого полиморфизма.

Клиенты ChildClass1 и ChildClass2 не должны различать их.

Нет места, где любой класс должен спрашивать о someObject.whoAmI().

Всякий раз, когда у вас возникает желание написать if someObject.whoAmI() == 'ChildClass1' { do X(someObject) }, вы действительно должны добавить метод X() в ParentClass с различными реализациями в различных ChildClasses.

Этот вид «идентификации типа во время выполнения» почти всегда можно заменить на правильные полиморфные конструкции классов.

1 голос
/ 10 ноября 2008

Начиная с PHP 5.3 это будет возможно с использованием статического ключевого слова , но пока это невозможно.

0 голосов
/ 17 сентября 2008

Нет. Ждите PHP 5.3.

...