Есть ли способ определить целевой класс в статических методах?

StackOverflow https://stackoverflow.com/questions/83887

  •  01-07-2019
  •  | 
  •  

Вопрос

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

<?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";
Это было полезно?

Решение 3

Теперь, когда 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().

Другие советы

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

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

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

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

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

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

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

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

Нет.Подождите PHP 5.3.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top