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

时间:2012-07-29 14:41:45

标签: php oop static php-5.3

  

可能重复:
  New self vs. new static

以下示例中使用selfstatic有什么区别?

class Foo
{
    protected static $bar = 1234;

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

}

Foo::instance();

产生

1234
1234

6 个答案:

答案 0 :(得分:165)

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

因此,如果您尝试在self::$bar课程的其他位置使用Foo但是您的Bar课程的属性值不同,则会使用Foo::$bar代替Bar::$bar,可能不是你想要的:

class Foo
{
    protected static $bar = 1234;
}

class Bar extends Foo
{
    protected static $bar = 4321;
}

当您使用static时,您正在调用名为late static bindings的功能(在PHP 5.3中引入)。

在上面的方案中,使用static代替self会导致使用Bar::$bar而不是Foo::$bar,因为解释程序会考虑重新声明Bar上课。

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

但是,这并不排除在static中使用属性。

答案 1 :(得分:43)

self - refers to the same class whose method the new operation takes place in.

static - in PHP 5.3's late static binding refers to whatever class in the hierarchy which you call the method on.

在下面的示例中(参见get_called_class()),B类继承了A类中的两个方法.Self绑定到A,因为它在A的方法实现中定义,而static绑定到被调用的类,尽管事实上它也在A的方法实现中。

class A {
    public static function get_A() {
        return new self();
    }

    public static function get_me() {
        return new static();
    }
}

class B extends A {}

echo get_class(B::get_A());  // A
echo get_class(B::get_me()); // B
echo get_class(A::get_me()); // A

答案 2 :(得分:2)

我有一个小示例显示selfstatic之间的区别。使用static::执行后期静态绑定,从而绑定子类中的变量值。

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

答案 3 :(得分:1)

如上所述,主要区别之一是static允许后期静态绑定。我发现的最有用的方案之一是为Singleton类创建基类:

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

在基类中使用return static::$name将返回扩展时静态附加的内容。如果要使用return self::$name,则B::getName()将返回一个空字符串,因为这是在基类中声明的。

答案 4 :(得分:1)

通过self通话:

class Foo
{
    protected static $var = 123;
    
    public function getVar()
    {
        return self::$var;
    }
}

class Bar extends Foo
{
    protected static $var = 234;
}

// Displays: "123"
echo (new Bar)->getVar();

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

现在,如果我们将呼叫与static交换,我们将获得Bar的替代值:

通过static通话:

class Foo
{
    protected static $var = 123;
    
    public function getVar()
    {
        return static::$var;
    }
}

class Bar extends Foo
{
    protected static $var = 234;
}

// Displays: "234"
echo (new Bar)->getVar();

答案 5 :(得分:1)

也许这段自我解释的代码可以帮助您:

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();

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

'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)