新的自我与新的静态

Mik*_*ike 483 php static late-static-binding

我正在转换PHP 5.3库以在PHP 5.2上工作.支持我的主要方法是使用后期静态绑定return new static($options);,如果我将其转换为return new self($options)将得到相同的结果?

new self和之间有什么区别new static

Bol*_*ock 840

我会得到相同的结果吗?

并不是的.不过,我不知道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
Run Code Online (Sandbox Code Playgroud)

  • 你不必"传递"类名,你总是可以做`get_called_class()`,它实际上与`__CLASS__`相同,但LSB兼容. (12认同)
  • <PHP5.3中不存在get_called_class.因此,如果你想在PHP5.2中获取实例化对象的类名这个函数在尝试将库从PHP 5.3转换为PHP 5.2时没有帮助 (7认同)
  • 在我的头脑中,我只是采取任何直觉的东西,然后使其相反。根据命名,您可能会认为“self”会返回自身,而“static”会返回无法被覆盖的内容……但你瞧,事实恰恰相反。PHP 的命名、约定和整体风格给我留下了深刻的印象。-_- (7认同)
  • 称为self :: theFunction()的函数的行为类似于“我将在我实际所属的类的上下文中执行”。并且称为static :: theFunction()的函数的行为类似于“我将在外界已实际调用的类的上下文中执行”。(假设继承方案)。谢谢 (2认同)

Mar*_*tis 20

如果此代码的方法不是静态的,您可以通过使用在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()));
Run Code Online (Sandbox Code Playgroud)

结果:

string(1) "B"
string(1) "B"
Run Code Online (Sandbox Code Playgroud)

  • 如果该方法不是静态的,则后期静态绑定变得完全无关紧要. (17认同)
  • @BoltClock肯定不是吗?如果你从子类的实例方法中调用一个重写的静态方法,那么你选择`self ::`或`static ::`将影响是否使用了该类静态方法的基类或子类的版本.在没有某种理由认为这种情况发生本质上表明不好的做法(并且我没有看到任何理由为什么应该如此),`self ::`和`static ::`之间的选择就像与非静态方法相关,就像在静态方法中一样.我误解了你的评论,还是我们错了? (8认同)
  • @Mark Amery:嗯,我没想到.你是绝对正确的.我假设在实例方法中没有调用静态方法,但根据你的例子,我可以看到这是一个非常幼稚的假设. (3认同)

Fat*_*ror 6

除了其他人的答案:

static ::将使用运行时信息进行计算。

这意味着您不能static::在类属性中使用,因为属性值:

必须能够在编译时进行评估,并且不能依赖于运行时信息。

class Foo {
    public $name = static::class;

}

$Foo = new Foo;
echo $Foo->name; // Fatal error
Run Code Online (Sandbox Code Playgroud)

使用 self::

class Foo {
    public $name = self::class;

}
$Foo = new Foo;
echo $Foo->name; // Foo
Run Code Online (Sandbox Code Playgroud)

  • 请注意,该错误引发在第2行`public $ name = static :: class;`上,而不是示例所建议的第7行。该错误表明:“ static :: class无法用于编译时类名称解析”,这表明问题不在您尝试访问$ name字段的位置,而是在编译PHP类之前。在第一个示例中,不会达到第7行(或第6行)。 (4认同)