PHP中的静态/早期绑定与动态/后期绑定

PHP中的静态/早期绑定与动态/后期绑定,php,Php,我相信我理解了静态/早期绑定与后期/动态绑定以及后期静态绑定的概念,但在阅读了几篇关于它的文章后,我发现了一些相互矛盾的定义 根据我的理解: <?php class A { protected $greeting = 'Hello from A'; public function hello() { echo $this->greeting; } } $obj = new A(); $

我相信我理解了静态/早期绑定与后期/动态绑定以及后期静态绑定的概念,但在阅读了几篇关于它的文章后,我发现了一些相互矛盾的定义

根据我的理解:

<?php
    class A {
       protected $greeting = 'Hello from A';

       public function hello() {
           echo $this->greeting;
       }
    }

    $obj = new A();
    $obj->hello();
是一个静态或早期绑定的示例,即使PHP是解释语言,也会在编译时发生。它是早期绑定,因为关于类的所有信息都是已知的&不需要动态计算,所以类和方法绑定发生在编译时

动态绑定或也称为后期绑定发生在运行时,而类和方法绑定发生在运行时。如果我们采用与上面相同的示例,但使用类似于继承的方法,则可能是延迟绑定或动态绑定:

 <?php
    class B extends A {           
       protected $greeting = 'Hello from B';
    }

    $obj = new B();
    $obj->hello();
所以我的问题是,我对静态/动态绑定的假设/理解在PHP中正确吗?我知道也有后期静态绑定,它结合了静态和后期绑定,并使静态属性和方法与继承一起工作,因此,您可以使用static::来代替self::来等待运行时进行绑定

以下是我在对自己对这一概念的理解产生疑问后阅读的文章,以供参考:

声明

使用作用域解析运算符时会发生静态绑定:

但根据我的理解,情况并非总是如此,我上面的例子中没有继承的不是静态绑定的一个版本吗?就绑定而言,静态并不一定意味着静态变量

以下文章中的信息相互矛盾,这就是为什么我有点困惑的原因&我想知道我是否正确理解它&我的例子是否正确。我在PHP上找不到原始的RFC,无法更深入地了解它到底是如何工作的


这些文章中哪一篇更能说明绑定在PHP中是如何工作的?

是的,您的理解是正确的,因为在创建类B并从A扩展它之后,函数hello有两个不同的版本,在运行时调用哪个版本取决于对象A或B的类型,这取决于调用它的上下文。另一种看待它的方式是多态性

。。。是一个静态或早期绑定的示例,即使PHP是解释语言,也会在编译时发生

你在一句话里把很多困惑都写进去了

首先,PHP是一种编译语言,它只是根据需要编译成高级中间表示形式。更重要的是,PHP是一种高度动态的语言,在编译过程中不会进行太多分析

其次,您展示的示例代码可以在编译时优化为已知的方法,但可能不是。就语言而言,语句$obj->hello;在运行时根据$obj的当前值进行评估。您可以在上面一行中看到要使用的类,并且知道该类没有父类,这并不意味着编译器肯定知道这些事情,并以不同的方式编译代码

第三,早期和静态不能仅仅用作同义词——否则,术语后期静态绑定将意味着后期早期绑定,并且没有任何意义。静态调用是引用特定类的调用;非静态调用是引用实例的调用

从用户的角度来看,重要的区别在于给定以下三行代码:

$someObject->methodOne; 自我评价:方法二; 静态:方法三; 使用的methodOne的定义将是代码运行时$someObject是其实例的任何类。如果$someObject具有不同的值,则每次运行代码行时可能会使用不同的方法。这是迟订的。 它还将引用$someObject中的特定实例,并将其放置在神奇变量$this中。这是一个非静态调用。 使用的methodTwo的定义将是该行代码所在的类中的定义。每次运行这行代码时,它都会引用同一个类。这是早期绑定。 使用的methodThree的定义将取决于代码的调用方式-如果使用methodThree自己版本的子类的名称调用它,则将使用该版本。与methodOne一样,该行每次可能运行不同的方法。这是迟订的。 Method2和Method3都只引用一个类,而不是一个实例。它们不会填充神奇变量$this。它们是静态调用。
谢谢你的回答谢谢你的详细解释。我弄糊涂了,因为多篇文章的信息相互矛盾。我已经用文章的链接更新了我的原始帖子。例如,根据您的回答codeproject.com/Articles/853792/…本文是错误的,因为它将静态绑定与动态绑定进行了比较&提到静态绑定也称为早期绑定 而动态绑定称为后期绑定。我认为这篇文章最接近你的解释方式。