New self vs. new static
我正在转换一个php 5.3库来处理php 5.2。在我看来,最主要的是使用像return new static($options);这样的后期静态绑定,如果我把它转换成return new self($options)我会得到同样的结果吗?
new self和new static有什么区别?
will I get the same results?
不是真的。不过,我不知道PHP5.2的解决方案。
What is the difference between new self and new static?
self是指实际写入new关键字的同一类。
在php 5.3后期的静态绑定中,static指的是您在层次结构中调用方法的任何类。
在下面的示例中,B继承了A的两个方法。self调用绑定到A上,因为它是在A的第一个方法的实现中定义的,而static绑定到被调用的类(另见get_called_class())。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| 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 |
- 有道理。我认为最好的办法是将类名传递给使用后期静态绑定的函数,然后返回新的$class name($options);
- 你不必"传递"类名,你可以一直做get_called_class(),这实际上与__CLASS__是一样的,但是与lsb兼容。
- get_called_class在
- 请参阅下面的get_class($this);
- 我也有类似的情况…如果你想看一下,我会非常感激的。stackoverflow.com/questions/22107831/…
- get_类($this)不起作用,这些是静态方法,没有$this
- 名为self::thefunction()的函数的行为类似于"我将在我物理上属于的类的上下文中执行"。而名为static::thefunction()的函数的行为类似于"我将在外部世界实际调用的类的上下文中执行"。(假设是继承场景)。谢谢
如果这段代码的方法不是静态的,您可以使用get_class($this)在5.2中找到解决方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| 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())); |
结果:
1 2
| string(1)"B"
string(1)"B" |
- 如果该方法不是静态的,那么后期的静态绑定将变得完全不相关。
- 例如,您可以在"copy"方法中使用它,在这种方法中,不使用clone复制对象,只需重新创建和设置属性。$copy = new static(); $copy->set($this->get()); return $copy;
- @波耳克肯定不是吗?如果从子类的实例方法中调用被重写的静态方法,那么您对self::或static::的选择将影响是否使用该静态方法的基类或子类版本。如果没有理由认为这种情况的发生本身就意味着不好的做法(我看不出有任何理由这样做),那么在非静态方法中,self::和static::之间的选择与静态方法中的选择同样重要。我是否误解了你的评论,或者我们之间的一方是错的?
- @马克:嗯,我没想到。你说得对。我假设在所讨论的实例方法中不会调用任何静态方法,但基于您的示例,我可以看到这是一个非常简单的假设。
- 后期静态绑定doc=>php.net/manual/en/language.oop5.late-static-bindings.php
- @博尔特克向你保证拥有它
除了其他人的答案:
static:: will be computed using runtime information.
这意味着您不能在类属性中使用static::,因为属性值:
Must be able to be evaluated at compile time and must not depend on run-time information.
1 2 3 4 5 6 7
| class Foo {
public $name = static::class;
}
$Foo = new Foo;
echo $Foo->name; // Fatal error |
使用self::。
1 2 3 4 5 6
| class Foo {
public $name = self::class;
}
$Foo = new Foo;
echo $Foo->name; // Foo |
- 注意,错误是在第2行public $name = static::class;上抛出的,而不是在第7行上抛出的,如示例所建议的那样。错误显示:"static::class不能用于编译时类名解析",这表明问题不在您试图访问$name字段的位置,而是在编译php类之前。在第一个示例中,不会到达第7行(或第6行)。
- @我在示例中所做的注释是为了显示最终结果,而不是指出错误实际发生的位置。但不管怎样,谢谢你指出这一点。
- 是的,我不是想批评,只是先澄清什么让我困惑,希望它能帮助别人。无论如何都是有用的例子!