PHP中的self :: $ bar和static :: $ bar有什么区别?

cwd*_*cwd 112 php oop php-5.3

可能重复:
新自我与新静态

使用selfstatic下面的例子有什么区别?

class Foo
{
    protected static $bar = 1234;

    public static function instance()
    {
        echo self::$bar;
        echo "\n";
        echo static::$bar;
    }

}

Foo::instance();
Run Code Online (Sandbox Code Playgroud)

产生

1234
1234
Run Code Online (Sandbox Code Playgroud)

Bol*_*ock 178

当您用于self引用类成员时,您指的是使用该关键字的类.在这种情况下,您的Foo类定义了一个名为的受保护静态属性$bar.当您selfFoo类中使用引用属性时,您引用的是同一个类.

因此,如果您尝试self::$barFoo类中的其他位置使用但是您有一个Bar具有不同属性值的类,它将使用Foo::$bar而不是Bar::$bar,这可能不是您想要的:

class Foo
{
    protected static $bar = 1234;
}

class Bar extends Foo
{
    protected static $bar = 4321;
}
Run Code Online (Sandbox Code Playgroud)

当您使用时static,您将调用一个名为late static bindings的功能(在PHP 5.3中引入).

在上面的场景中,使用self而不是Foo::$bar将导致static使用而不是Bar::$bar,因为解释器然后考虑了static类内的重新声明.

您通常对方法使用后期静态绑定,甚至使用类本身而不是属性,因为您不经常在子类中重新声明属性; Bar在这个相关的问题中可以找到使用关键字来调用后期绑定构造函数的示例:New self vs. new static

但是,这并不排除使用static属性.

  • 转到[phpfiddle.org](http://phpfiddle.org/)并运行此`<?php类Foo {public static $ bar = 1234; 公共静态函数a(){echo'static'.static :: $ bar; 回声'self'.self :: $ bar; }}类Bar扩展Foo {public static $ bar = 4321; }(new Bar())-> a(); ?>` (3认同)
  • 前两段措辞令人困惑,有一个含糊不清的代词“it”,而且也是多余的,因为后面的段落更清楚地解释了相同的信息。我建议用后面的段落替换前两段,后面的段落以“在上述场景中”开头。这样,底线、切入主题的答案就位于顶部。它清晰易懂。 (2认同)

Jso*_*owa 14

我有一个小例子显示self和之间的区别static。Usingstatic::执行后期静态绑定,因此它绑定来自子类的变量值。

class A { // Base Class
    protected static $name = 'ClassA';
    public static function getSelfName() {
        return self::$name;
    }
    public static function getStaticName() {
        return static::$name;
    }
}

class B extends A {
    protected static $name = 'ClassB';
}

echo B::getSelfName(); // ClassA
echo B::getStaticName(); // ClassB
Run Code Online (Sandbox Code Playgroud)


Ste*_*man 8

self电话:

class Phone
{
    protected static $number = 123;
    
    public function getNumber()
    {
        return self::$number;
    }
}
Run Code Online (Sandbox Code Playgroud)
class Fax extends Phone
{
    protected static $number = 234;
}

// Displays: "123"
echo (new Fax)->getNumber();
Run Code Online (Sandbox Code Playgroud)

您可以在上面看到,即使我们$number用我们的Fax类覆盖了,它仍然返回123,因为我们已经明确要求 PHP 提供self变量,而PHP反过来要求Phones 变量。

现在,如果我们用 交换self调用static,我们将获得Faxs 覆盖的值:

static电话:

class Phone
{
    protected static $number = 123;
    
    public function getNumber()
    {
        return static::$number;
    }
}
Run Code Online (Sandbox Code Playgroud)
class Fax extends Phone
{
    protected static $number = 234;
}

// Displays: "234"
echo (new Fax)->getVar();
Run Code Online (Sandbox Code Playgroud)

  • 非常直接且不令人困惑的示例。 (2认同)

gge*_*dde 6

如前所述,主要区别之一是static允许后期静态绑定。我发现的最有用的场景之一是为单例类创建基类:

class A { // Base Class
    protected static $name = '';
    protected static function getName() {
        return static::$name;
    }
}
class B extends A {
    protected static $name = 'MyCustomNameB';
}
class C extends A {
    protected static $name = 'MyCustomNameC';
}

echo B::getName(); // MyCustomNameB
echo C::getName(); // MyCustomNameC
Run Code Online (Sandbox Code Playgroud)

使用return static::$nameBase类将返回时,又延长了什么静态连接。如果您要使用return self::$namethenB::getName()将返回一个空字符串,因为这是在 Base 类中声明的内容。


dwo*_*ing 5

也许这个不言自明的代码可以帮助你:

class Foo 
{
    protected static $bar = 'parent value';

    public static function test() 
    {
        var_dump('I am your father');
        var_dump('self:: here means '.self::$bar);
        var_dump('static:: here means '.static::$bar);
    }
}

class Bar extends Foo 
{
    protected static $bar = 'child value';

    public static function test() 
    {
        parent::Test();

        var_dump('I am the child');
        var_dump('self:: here means '.self::$bar);
        var_dump('static:: here means '.static::$bar);
    }
}

Bar::test();
Foo::test();
Run Code Online (Sandbox Code Playgroud)

这会产生以下输出(为了清楚起见,我添加了换行符):

'I am your father' (length=16)
'self:: here means parent value' (length=30)
'static:: here means child value' (length=31)

'I am the child' (length=14)
'self:: here means child value' (length=29)
'static:: here means child value' (length=31)

'I am your father' (length=16)
'self:: here means parent value' (length=30)
'static:: here means parent value' (length=32)
Run Code Online (Sandbox Code Playgroud)