我正在上一个抽象课程,以节省几个类的代码。这些课程都是通过不同的静态调用实例化的工厂。我可以通过将所有这些方法放入抽象类中来保存一些代码。

但是,我遇到了 晚期静态结合 问题...由于我们的Web主机不使用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