php - 从类中静态调用实例方法

标签 php

根据其中一个手册页 http://www.php.net/manual/en/language.oop5.static.php :

Calling non-static methods statically generates an E_STRICT level warning.

但是,当从类内部进行调用时,情况似乎并非如此:

error_reporting(-1);

class Test {
    private $id;
    function __construct($id) { $this->id = $id; }
    function id() { return $this->id; }

    function __toString() {
        return Test::id()
             . self::id()
             . static::id()
             . static::id()
             . call_user_func('Test::id')
             . call_user_func(array('Test', 'id'));
    }
}
$a = new Test('a');
$b = new Test('b');


echo "$a $b $a"; # aaaaaa bbbbbb aaaaaa
var_dump(error_get_last()); # NULL

用 php 5.4 测试

演示: http://codepad.viper-7.com/IKp9iX

我相信我已经证明了:

  • 没有生成 E_STRICT 警告
  • 那个 php 神奇地将静态方法调用更正为实例方法调用(访问实例变量 id 证明了这一点)。

编辑- 我想添加插入 debug_backtrace () 到 __toString 调用中产生 -> 的调用“类型”,这意味着“方法调用”。

这是错误还是已记录的功能?

最佳答案

如果您在任何类(不仅仅是声明类)中使用静态语法调用非静态函数,则该非静态函数的行为就好像它被调用一样在当前 $this 对象的上下文中。

这意味着我可以在我的类中使用其他类的方法,并且这些方法将假设我类的$this是他们的类的$this。如果它们不检查 InstanceOfget_class(),它们的行为将与往常完全一样。

当我像往常一样说时,我的意思是他们会假定您的类的 $this 具有他们的类的 $this 将具有的所有其他方法和属性。

这(我认为)称为对象上下文绑定(bind)。在 JavaScript 中,您必须使用那些 call() 和/或 apply() 方法来使函数的行为就像它附加到某个对象一样。但在 PHP 中,它只是通过在非静态函数上使用静态语法来工作。

我记得这在 C++ 中也有效,但我不记得它是否仅在方法属于继承类时有效(尽管它们被覆盖,但您可能想要访问的覆盖方法)。

使用此(隐藏)功能,您可以实现Decorator 设计模式,通过该模式可以在运行时向对象添加新功能。您还可以模拟 MixinsTraits(PHP 5.4 现在原生支持),额外的好处是此实现在运行时处理,因此可以完成/撤消与在编译时处理并且不能动态完成/撤消的语言功能实现相反,您必须更改代码才能更改功能。

关于php - 从类中静态调用实例方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11165429/

相关文章:

使用for循环的递增日期的php代码在更新条件下不起作用

php - 从 cer 文件中提取公钥以在 nusoap 中使用

php - 如何在 MySQL 数据库中存储 PHP 常量

php - 获取某个 channel 的所有 YouTube 视频(某些视频丢失)

php - 扩展 Doctrine Entity 以添加业务逻辑

php - ZendSearch Lucene bool 查询不能正确处理数字

php - pdo 和 mysqli 在同一个项目中

php array_splice() 空数组

php - 收到有关库存不可用的通知

php - 从所选变体向 WooCommerce 变量产品标题添加一些属性值