PHP 5.3静态::后期绑定的奇怪行为

时间:2013-08-17 14:47:06

标签: php yii php-5.3

<?php

class baseModel
{
    public static function show($className=__CLASS__)
    {
        print_r($className);
    }

    public function test()
    {
        static::show();
    }
}

class AModel extends baseModel 
{
    public static function show($className=__CLASS__)
    {
        print_r($className);
    }
}

class Controller
{
    public function actionTest()
    {
        baseModel::test();
        AModel::test();
    }
}

$c = new Controller;
$c->actionTest();
?>

预期产出:

baseModelAModel

实际输出:

Fatal error: Call to undefined method Controller::show() in /var/www/dashboard/test.php on line 12

为什么PHP会尝试查找Controller::show()而不是AModel::show

2 个答案:

答案 0 :(得分:2)

static关键字是指上下文,而不是方法定义的类。因此,当您从C的上下文调用A::test时,static指的是C。

答案 1 :(得分:2)

php manual

中写道
  

在非静态上下文中,被调用的类将是对象实例的类。由于$ this-&gt;将尝试从同一范围调用私有方法,使用static ::可能会给出不同的结果。另一个区别是static ::只能引用静态属性。

这意味着在对象$c(类Controller)的上下文中,在方法{{1}中进行非静态调用($c->t())后期绑定static::关键字引用对象引用baseModel::test()的类,它是$this而不是类,而如果调用static:

Controller

Controller::test(); 的上下文称为类。

但是我建议你不要使用静态调用,除非将方法明确定义为static:

static::

此代码有效,因为如果明确定义class baseModel { public static function show($className=__CLASS__) { print_r($className); } public static function test() // must be defined as static or context of static:: may change to Controller instead of actual class being called! { static::show(); } } 作为baseModel::test()的静态上下文将永远是静态的。