返回

PHP 中 `new self` 和 `new static` 的本质区别:晚期静态绑定的奥秘

php

new selfnew static:晚期静态绑定的奥秘揭秘

简介

在 PHP 5.3 中引入的晚期静态绑定(Lsb)为 PHP 语言增添了强大的新功能,其中之一就是 new static 操作符。new static 与传统的 new self 操作符有什么区别?在 PHP 5.2 中将 new static 转换为 new self 会产生相同的效果吗?本文将深入探究这些问题,帮助您理解 Lsb 的细微差别。

selfstatic 的本质

self:

  • 指代当前类的名称。
  • 在类的非静态方法中使用时,它指向当前对象。

static:

  • 指代当前类的静态作用域,而不指向当前对象。
  • 在类的静态方法中使用时,它指向当前类。

new selfnew static 的区别

new self:

  • 在当前类的上下文中创建一个新对象。
  • 使用当前类的名称和作用域。

new static:

  • 在当前类的静态作用域中创建一个新对象。
  • 使用调用 new static 的类的名称和作用域。

在继承中的表现

继承链中:

  • 在父类中使用 new self 创建子类的新对象。
  • 在子类中使用 new static 创建父类的新对象。

原因:

  • self 在子类中指向子类本身,而在父类中指向父类。
  • static 在子类中指向父类,因为父类是子类的静态作用域。

PHP 5.2 中的兼容性

在 PHP 5.2 中,new static 操作符并不存在。因此,编译器会将 new static 转换为 new self

相同的结果吗?

通常情况下,在 PHP 5.2 中将 new static 转换为 new self 会产生相同的结果。但是,在涉及继承时,可能会出现细微差别。

示例

class Parent {
    public static function create() {
        return new static();
    }
}

class Child extends Parent {
    public static function create() {
        return new static();
    }
}

$parentObject = Parent::create(); // Parent 对象
$childObject = Child::create(); // Child 对象

在 PHP 5.3 中,$parentObjectParent 对象,而 $childObjectChild 对象(因为 static 指向调用 create 方法的类)。

在 PHP 5.2 中,由于 new static 被转换为 new self$parentObject$childObject 都是 Parent 对象(因为 selfChild 中指向 Parent)。

总结

  • new self 创建当前类的对象,new static 创建调用 new static 的类的对象。
  • 在继承中,new selfnew static 的行为有所不同。
  • 在 PHP 5.2 中,new static 被转换为 new self,但这可能会在继承场景中产生微妙的差异。

常见问题解答

Q1:new selfnew static 在何种情况下可以互换?
A1: 在不涉及继承的场景中,它们通常可以互换。

Q2:new static 的优势是什么?
A2: new static 允许在子类中创建父类的对象,这在某些设计模式中很有用。

Q3:new selfnew static 在性能上有什么区别?
A3: 没有已知的性能差异。

Q4:为什么 new static 不存在于 PHP 5.2 中?
A4: new static 是 Lsb 的一部分,Lsb 是 PHP 5.3 中引入的新特性。

Q5:如何强制在 PHP 5.2 中使用 new static
A5: 没有简单的方法。建议升级到 PHP 5.3 或更高版本。