PHP에서 self :: $ bar와 static :: $ bar의 차이점은 무엇입니까?


125

사용의 차이 무엇입니까 self그리고 static아래의 예는?

class Foo
{
    protected static $bar = 1234;

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

}

Foo::instance();

생산하다

1234
1234

2
@deceze : 비슷한 질문이지만 중복이 아닙니다. 이것은 속성과 함께 키워드를 사용하는 것에 대해 묻고 생성자와 함께 사용하는 것에 대해 묻습니다.
BoltClock

답변:


191

당신이 사용하는 경우 self클래스 멤버를 참조 할, 당신은 당신이 키워드를 사용하는 내부 클래스를 참조하고 있습니다. 이 경우 Foo클래스는라는 보호 된 정적 속성을 정의합니다 $bar. 속성을 참조하기 self위해 Foo클래스 에서 사용 하면 동일한 클래스를 참조하는 것입니다.

따라서 클래스의 self::$bar다른 곳에서 사용하려고했지만 속성에 대해 다른 값을 가진 클래스가있는 경우 대신을 사용 하며 이는 의도 한 바가 아닐 수 있습니다.FooBarFoo::$barBar::$bar

class Foo
{
    protected static $bar = 1234;
}

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

당신은 때 전화 를 통한 방법 static, 당신이라는 기능을 호출하고 늦게 정적 바인딩 (PHP 5.3에서 도입을).

위의 시나리오에서를 사용 self하면 Foo::$bar(1234)가됩니다. 를 사용 static하면 인터프리터가 런타임 중에 클래스 내의 재 선언을 고려 Bar::$bar하기 때문에 (4321)이 됩니다.staticBar

일반적으로 하위 클래스에서 속성을 다시 선언하지 않기 때문에 속성보다는 메서드 또는 클래스 자체에 대해 후기 정적 바인딩을 사용합니다. static후기 바인딩 생성자를 호출하기 위해 키워드를 사용하는 예는 다음과 같은 관련 질문에서 찾을 수 있습니다. New self vs. new static

그러나 static속성과 함께 사용하는 것도 배제하지 않습니다 .


자식 클래스에서 매우 쉽게 다시 선언 할 수 있으며 부모 클래스는 다시 선언하지 않는 한 자식 클래스가 사용하는 기본값이 될 수 있습니다. 부모 클래스에 있다면 self ::를 사용하는 것이 안전하다고 생각하고 자식 클래스에서는 둘 중 하나를 사용할 인수를 생각 해낼 수 있지만 self ::는 예상하지 않으면 작동합니다. 다시 선언하십시오.
Andrew

3
phpfiddle.org 로 이동하여 실행<?php class Foo { public static $bar = 1234; public static function a( ) { echo 'static'.static::$bar; echo 'self'.self::$bar; } } class Bar extends Foo { public static $bar = 4321; } (new Bar())->a(); ?>
Yevgeniy Afanasyev

2
처음 두 단락의 표현은 혼란스럽고, 모호한 대명사 "it"이 있으며, 이후 단락에서 동일한 정보를 더 명확하게 설명하기 때문에 중복됩니다. 처음 두 단락을 "위 시나리오에서"로 시작하는 이후 단락으로 바꾸는 것이 좋습니다. 그런 식으로 결론, 추격전 답변이 맨 위에 있습니다. 명확하고 따라하기 쉽습니다.
ahnbizcad

이것에 대해 생각하는 또 다른 방법 : self::$abc, 내부에서 사용 class Foo하는 것은 말하는 것과 같습니다 Foo::$abc. $abc하위 클래스에서의 재 선언에 영향을받지 않습니다 . AFAIK를 사용하는 유일한 이유 selfFoo더 길 수있는 클래스 이름을 사용하지 않기위한 속기 입니다. [이것은 또한 모든 위치를 변경하지 않고 클래스 이름을 변경할 수 있음을 의미하지만 IMHO의 이유가별로 없습니다.] (PHP의 이름 선택은 불행하고 거꾸로 보입니다. "정적"은 변경할 수있는 이름입니다. 자연어 단어 "정적"의 구어 적 의미와 반대입니다.)
ToolmakerSteve

4

언급했듯이 주요 차이점 중 하나는 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

return static::$nameBase 클래스에서 사용하면 확장 될 때 정적으로 첨부 된 항목이 반환됩니다. 당신이 사용한다면 return self::$name다음 B::getName()그 기본 클래스에 선언되어 무엇으로 빈 문자열을 반환합니다.


0

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

당신은 우리가를 오버라이드 (override)에도 불구하고, 위의 볼 수있는 $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();
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.