php - 在 PHP 中使用 $this 和 self::有什么意义?

标签 php language-design

为什么 PHP 要求您显式编写 $this?如果您必须在此处使用 $this,我会理解:

function foo($bar) {
   $this->bar = $bar;
}

但是你必须用像这样的冗长代码明确地编写它:

$this->var3 = globalFun($this->var, $this->var2[$this->anotherVar], $this->method());

相对于:

$var3 = globaFun($var, $var2[$anotherVar], method());

那么$this有什么意义呢?

附加奖励问题:

为什么我们要区分静态引用和实例?我们为什么需要:

static function getValue() {
   return self::value;
}

如果有问题的变量/方法是静态的,PHP 不能在运行时发现吗?现在,如果我想将一个方法从静态更改为非静态,我必须将所有那些 self:: 替换为 $this->(反之亦然)。

如果我们有一个表现得像在 Java 中那样的 $this 会不会更好?

最佳答案

由于重新打开,我会在这里发布 my answer , 正如所 promise 的那样。

TL;DR version 如果不需要限制成员访问,不仅会降低性能,而且同一行代码可能同时表示字段访问和局部变量访问,取决于代码路径。

完整版

在 PHP 中,表中始终有一个事件的符号表。这要么是全局符号表,要么是函数/方法局部符号表(顺便说一下,它们是懒惰构建的)。除了超全局变量和编译变量之类的优化,当请求变量 $var 时,它会在当前符号表中查找。由于对象属性不存在于符号表中,而是存在于对象(实例属性)或与类相关的结构(静态属性)中,因此对 $var 的查找永远不会返回一个属性。

要将给定变量引入函数作用域,您必须通过创建引用来明确表示您的意图。示例:

$myglobal = 7;
class A {
    private $prop;
    public function meth() {
        global $myglobal; //bring a global to the current scope
        $prop =& $this->prop; //brings a property to the current scope
        $local = 4;
        $lambda = function () use (&$local) { };
    }
}

显然,这只是一种更复杂的方式来表达当前发生的事情。问题是为什么会出现这种行为?

毕竟,在 Java 中,当有一个名为 prop 的局部变量隐藏该属性时,我们只需键入 this.prop。为什么这不是 PHP 的好选择?

我能想到几个原因。

对象属性在运行时确定

PHP 有一种叫做“动态属性”的东西。您可以在运行时为对象分配新属性。事实上,给定同一类的两个对象,一个可以具有给定属性 $a 而另一个则没有。示例:

$obj1 = new stdClass();
$obj2 = new stdClass();
$obj1->a = 7;

在PHP中,定义的局部变量是在运行时确定的

变量不必声明;因此,根据代码路径,在某些时候可能会或可能不会定义变量。雪上加霜的是,我们还有一个叫做“可变变量”的怪物。示例:

class A {
    private $g = 3;
    public function func($varname) {
        if (rand(1,2) == 1) {
            $g = 4; //no block scope; the scope is the function's
        }
        $$varname = 5; //god knows what's happening here
        //if local variables hid properties, we'd have trouble
    }
}

在 Java 中,给定的标识符也可以在同一个函数内表示一个局部变量和一个属性,但是:

  • 不在同一 block 内(在 PHP 中,函数中的所有 block 共享完全相同的范围)。
  • 如果您隐藏属性,您会收到警告。
  • 至关重要的是,在标识符的任何给定出现中,它都是属性或局部变量,它不能有时是一个,有时又是另一个。

后果

由于这些事实,不可能在编译时确定 $var 是指局部变量还是指属性。因此:

  • 在运行时,每次出现变量时,它必须先在本地符号表中查找,然后在实例属性表中查找,最后在静态属性列表中查找,或任何其他顺序(因为不能是一个实例和一个具有相同名称的静态属性,并且需要声明静态属性,这里会有一些优化潜力,但重点是)。这意味着在最坏的情况下,必须在三个不同的地方查找一个符号。从性能的角度来看,这很糟糕。
  • 一个给定的符号出现在不同的场合可能意味着不同的事情。这是灾难的根源。

关于php - 在 PHP 中使用 $this 和 self::有什么意义?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3345408/

相关文章:

php - 使用php搜索pdf中的文本

C# 设计 : Why is new/override required on abstract methods but not on virtual methods?

swift - 为什么Swift也需要参数名称(如果它也需要参数顺序)?

jvm - 什么是开发爱好语言的好 VM?

scala - 为什么所有基本的不可变集合都是最终的或密封在scala中的?

PHP:将匿名函数作为参数传递

php - 嵌套 mysql 查询在 codeigniter 中不起作用

php - 对不同查询求和

php - 上传图片到主机

haskell - 为 'lambda' , 'define' 生成 LLVM 代码