在php 5.3之前伪造后期静态绑定

Tys*_*est 11 php oop static

我需要一个继承的静态函数"call"来调用另一个被覆盖的静态函数"inner".我可以用后期静态绑定做到这一点,但我的主机还没有php5.3,所以我需要解决它.

class ClassA{
    static function call()
    {
        return self::inner();
    }

    static function inner(){
        return "Class A";
    }   
}

class ClassB extends ClassA{
    static function inner(){
        return "Class B";
    }
}

echo "<p>Class A = " . ClassA::call();
echo "<p>Class B = " . ClassB::call();
Run Code Online (Sandbox Code Playgroud)

我希望输出为:
A
类= A 类B类= B类

但它是什么:
A
类= A 类B类= A 类

我的直觉告诉我,我应该能够在call()中写一些东西,以便在调用"call()"时检测被引用的对象.因此,而不是self :: inner(),它会沿着calledclass :: inner()的方向发展.检测从原始方法调用调用的内部()的正确版本.

tro*_*skn 1

您可以使用对象实例而不是类。如果需要全局符号,可以使用全局变量。由于它们在 PHP 中相当笨重,因此一个技巧是将其包装在函数中。例如。:

class ClassA {
  function call() {
    return $this->inner();
  }
  function inner() {
    return "Class A";
  }   
}
function ClassA() {
  static $instance;
  return $instance ? $instance : new ClassA();
}

class ClassB extends ClassA {
  function inner() {
    return "Class B";
  }
}
function ClassB() {
  static $instance;
  return $instance ? $instance : new ClassB();
}

echo "<p>Class A = " . ClassA()->call();
echo "<p>Class B = " . ClassB()->call();
Run Code Online (Sandbox Code Playgroud)

但更好的想法可能是完全避免全局符号;它在 Ruby/Rails 中运行良好的原因是 Ruby 并不像 PHP 那样真正具有静态状态。类可以在运行时重新绑定和添加,这样可以轻松扩展框架。在 PHP 中,类始终是最终的,因此在应用程序代码中引用它们是一种非常强的耦合。