【发布时间】:2026-01-13 03:50:01
【问题描述】:
我正在转换 PHP 5.3 库以在 PHP 5.2 上运行。阻碍我的主要事情是使用像 return new static($options); 这样的后期静态绑定,如果我将其转换为 return new self($options) 会得到相同的结果吗?
new self 和 new static 有什么区别?
【问题讨论】:
标签: php static late-static-binding
我正在转换 PHP 5.3 库以在 PHP 5.2 上运行。阻碍我的主要事情是使用像 return new static($options); 这样的后期静态绑定,如果我将其转换为 return new self($options) 会得到相同的结果吗?
new self 和 new static 有什么区别?
【问题讨论】:
标签: php static late-static-binding
我会得到相同的结果吗?
不是真的。不过,我不知道 PHP 5.2 的解决方法。
new self和new static有什么区别?
self 指的是实际写入new 关键字的同一类。
static,在 PHP 5.3 的后期静态绑定中,指的是层次结构中您调用该方法的任何类。
在以下示例中,B 继承了 A 的两个方法。 self 调用绑定到 A,因为它是在 A 的第一个方法的实现中定义的,而 static 绑定到被调用的类(另见 get_called_class())。
class A {
public static function get_self() {
return new self();
}
public static function get_static() {
return new static();
}
}
class B extends A {}
echo get_class(B::get_self()); // A
echo get_class(B::get_static()); // B
echo get_class(A::get_self()); // A
echo get_class(A::get_static()); // A
【讨论】:
get_called_class(),这实际上与__CLASS__ 相同,但与LSB 兼容。
self 会返回自己,static 会返回一些不能被覆盖的东西......但是你瞧,情况恰恰相反。 PHP 的命名、约定和整体风格给我留下了深刻的印象。 -_-
如果此代码的方法不是静态的,您可以在 5.2 中使用get_class($this) 获得解决方法。
class A {
public function create1() {
$class = get_class($this);
return new $class();
}
public function create2() {
return new static();
}
}
class B extends A {
}
$b = new B();
var_dump(get_class($b->create1()), get_class($b->create2()));
结果:
string(1) "B"
string(1) "B"
【讨论】:
clone,而只需重新创建和设置属性即可。 $copy = new static(); $copy->set($this->get()); return $copy;
self:: 或static:: 的选择将影响是使用该静态方法的基类版本还是子类版本。在没有理由认为这种情况的发生本质上表明不良做法的情况下(我认为没有任何理由应该如此),self:: 和 static:: 之间的选择在非静态方法,就像在静态方法中一样。我是否误解了您的评论,或者我们只是错了?
除了别人的回答:
static:: 将使用运行时信息进行计算。
这意味着您不能在类属性中使用static::,因为属性值:
必须能够在编译时进行评估,并且不得依赖于运行时信息。
class Foo {
public $name = static::class;
}
$Foo = new Foo;
echo $Foo->name; // Fatal error
使用self::
class Foo {
public $name = self::class;
}
$Foo = new Foo;
echo $Foo->name; // Foo
请注意,我所做的代码中的致命错误注释并未指出错误发生的位置,该错误在对象被实例化为 cmets 中提到的@Grapestain 之前发生过
【讨论】:
public $name = static::class; 上引发的,而不是在第 7 行上,如示例所示。错误说:“static::class cannot be used for compile-time class name resolution”,这表明问题不在于您尝试访问 $name 字段的位置,而是在 PHP 类的编译之前。在第一个示例中将无法到达第 7 行(或第 6 行)。