Вопрос

Я работал над абстрактным классом, чтобы сохранить на некоторых коде для нескольких классов. Эти классы - это все фабрики, которые создавали себя через различные статические вызовы. Я мог сэкономить какой-код, положив все эти методы в абстрактный класс.

Тем не менее, я столкнулся с Позднее статическое обязательство Проблема ... Поскольку наш веб-хост не использует 5,3 или позже, у меня нет доступа к get_called_class. Если у меня есть

$class = __CLASS__;
return new $class();

в абстрактном классе, __CLASS__ Название абстрактного класса, когда я действительно хочу, чтобы он использовал под названием класс.

Я видел примеры абстрактных фабрик в Интернете, где у детей-классов есть собственные методы создания инсультаций, и не полагаются на абстрактный родитель для него. Однако в этой ситуации единственная причина для абстрактного класса состоит в том, чтобы сохранить код, поэтому, если я не могу сделать это там, значение оно значительно уменьшается.

Есть ли обходной путь в PHP <5.3? debug_backtrace()?


Редактировать:

Я сделал тест, и кажется debug_backtrace() не будет работать! Я думаю, вот почему нам нужно Позднее статическое обязательство.

<?

abstract class abstractFactory {
    public function create() {
            print_r(debug_backtrace());
            $class = __CLASS__;
            return new $class();
    }
}

class concreteFactory extends abstractFactory {}

$chimborazo = concreteFactory::create();

И результат:

$ php test.php
Array
(
    [0] => Array
        (
            [file] => /var/www/test.php
            [line] => 13
            [function] => create
            [class] => abstractFactory
            [type] => ::
            [args] => Array
                (
                )

        )

)

Fatal error: Cannot instantiate abstract class abstractFactory in /var/www/test.php on line 7
Это было полезно?

Решение 3

Размещение способа сделать это, чтобы переопределить различные методы создания инсультаций и передайте имя класса напрямую:

<?

abstract class abstractFactory {

    public function create($class) {
        return new $class();
    }

    public function instantiate($class) {
        return new $class();
    }

}

class concreteFactory extends abstractFactory {

    public function create() {
        parent::create(__CLASS__);
    }

    public function instantiate() {
        parent::instantiate(__CLASS__);
    }
}


$chimborazo = concreteFactory::create();
$chimborazo = concreteFactory::instantiate();

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

Единственный обходной путь, который я видел для этого, включает в себя звонить debug_backtrace. Определить название класса абонента (ы). Это, конечно, гигантский взлом. Я видел какой-нибудь код, который сочетает в себе задницу с на самом деле открытие вызова файла и разбирая его понять вещи. Причудливые, ужасные вещи.

Недостаток LSB собирается вернуться и укусить вас позже. Обновите сейчас, даже если это означает коммутационные хосты. На самом деле, особенно если это означает коммутационные хосты. 5.3 уже в течение года.

Вот что я использовал до перехода на 5,3:

if (!function_exists('get_called_class')) {

   /**
    * Implementation of get_called_class() for pre-5.3 PHP
    *
    * @return string
    */
   function get_called_class()
   {
      $bt = debug_backtrace();
      $lines = file($bt[1]['file']);
      preg_match('/([a-zA-Z0-9\_]+)::'.$bt[1]['function'].'/',
               $lines[$bt[1]['line']-1],
               $matches);
      return $matches[1];
   }
}

Это позволяет определить в статической функции, какое имя класса была вызвана функция. Это обходной путь, который имеет некоторые проблемы с производительностью, но это единственное, что я нашел. Если есть другие, мне интересно узнать.

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