복붙노트

$ this 위에 자기를 사용할 때?

PHP

$ this 위에 자기를 사용할 때?

PHP 5에서 self와 $ this를 사용하는 것의 차이점은 무엇입니까?

각각 적절한시기는 언제입니까?

해결법

  1. ==============================

    1.

    다음은 비 정적 및 정적 멤버 변수에 대한 $ this와 self의 올바른 사용 예입니다.

    <?php
    class X {
        private $non_static_member = 1;
        private static $static_member = 2;
    
        function __construct() {
            echo $this->non_static_member . ' '
               . self::$static_member;
        }
    }
    
    new X();
    ?>
    

    다음은 비 정적 및 정적 멤버 변수에 대한 $ this와 self의 잘못된 사용 예입니다.

    <?php
    class X {
        private $non_static_member = 1;
        private static $static_member = 2;
    
        function __construct() {
            echo self::$non_static_member . ' '
               . $this->static_member;
        }
    }
    
    new X();
    ?>
    

    다음은 멤버 함수에 대한 $ this를 사용한 다형성의 예입니다.

    <?php
    class X {
        function foo() {
            echo 'X::foo()';
        }
    
        function bar() {
            $this->foo();
        }
    }
    
    class Y extends X {
        function foo() {
            echo 'Y::foo()';
        }
    }
    
    $x = new Y();
    $x->bar();
    ?>
    

    다음은 멤버 함수에 self를 사용하여 다형성 동작을 억제하는 예제입니다.

    <?php
    class X {
        function foo() {
            echo 'X::foo()';
        }
    
        function bar() {
            self::foo();
        }
    }
    
    class Y extends X {
        function foo() {
            echo 'Y::foo()';
        }
    }
    
    $x = new Y();
    $x->bar();
    ?>
    

    http://www.phpbuilder.com/board/showthread.php?t=10354489에서 :

    http://board.phpbuilder.com/member.php?145249-laserlight

  2. ==============================

    2.

    키워드 self는 최소한 정적 인 멤버로 제한하는 방식이 아닌 '현재 클래스'를 참조하지 않습니다. 비 정적 멤버 컨텍스트 내에서 self는 현재 객체에 대한 vtable (vtable의 wiki 참조)을 우회하는 방법을 제공합니다. parent :: methodName ()을 사용하여 부모 버전의 함수를 호출 할 수 있으므로 self :: methodName ()을 호출하여 메소드의 현재 클래스 구현을 호출 할 수 있습니다.

    class Person {
        private $name;
    
        public function __construct($name) {
            $this->name = $name;
        }
    
        public function getName() {
            return $this->name;
        }
    
        public function getTitle() {
            return $this->getName()." the person";
        }
    
        public function sayHello() {
            echo "Hello, I'm ".$this->getTitle()."<br/>";
        }
    
        public function sayGoodbye() {
            echo "Goodbye from ".self::getTitle()."<br/>";
        }
    }
    
    class Geek extends Person {
        public function __construct($name) {
            parent::__construct($name);
        }
    
        public function getTitle() {
            return $this->getName()." the geek";
        }
    }
    
    $geekObj = new Geek("Ludwig");
    $geekObj->sayHello();
    $geekObj->sayGoodbye();
    

    그러면 다음과 같이 출력됩니다.

    sayHello ()는 $ this 포인터를 사용하므로 vtable이 호출되어 Geek :: getTitle ()을 호출합니다. sayGoodbye ()는 self :: getTitle ()을 사용하므로 vtable이 사용되지 않고 Person :: getTitle ()이 호출됩니다. 두 경우 모두 인스턴스화 된 객체의 메서드를 처리하고 호출 된 함수 내에서 $ this 포인터에 액세스 할 수 있습니다.

  3. ==============================

    3.

    self ::를 사용하지 말고 static을 사용하십시오 ::

    self ::의 또 다른 측면은 언급할만한 가치가 있습니다. annoyingly self ::는 실행 시점이 아닌 정의 시점의 범위를 나타냅니다. 두 가지 방법으로이 간단한 클래스를 살펴보십시오.

    class Person
    {
    
        public static function status()
        {
            self::getStatus();
        }
    
        protected static function getStatus()
        {
            echo "Person is alive";
        }
    
    }
    

    Person :: status ()를 호출하면 "Person is alive"가 표시됩니다. 이제 우리가 이것으로부터 상속받은 클래스를 만들 때 어떤 일이 일어나는지 생각해보십시오 :

    class Deceased extends Person
    {
    
        protected static function getStatus()
        {
            echo "Person is deceased";
        }
    
    }
    

    Deceased :: status ()를 호출하면 "Person is deceased"가 표시됩니다. 그러나 self :: getStatus ()에 대한 호출이 정의되었을 때 범위에 원래 메서드 정의가 포함되어 있으므로 "Person is alive"가 표시됩니다.

    PHP 5.3에는 해결책이 있습니다. static :: resolution 연산자는 "late static binding"을 구현합니다.이 바인딩은 호출 된 클래스의 범위에 바인딩되어 있다는 멋진 표현입니다. status ()의 줄을 static :: getStatus ()로 변경하면 결과는 예상대로입니다. 이전 버전의 PHP에서는이 작업을 수행하기 위해 골치 거리를 찾아야합니다.

    PHP 문서보기

    질문에 대답하지 말고 ...

    $ this->는 현재 객체 (클래스의 인스턴스)를 참조하는 반면, static ::은 클래스를 참조합니다.

  4. ==============================

    4.

    우리가 자기 자신에 대해 이야기 할 때 우리가 이야기하고있는 것을 실제로 이해하기 위해서는 개념적이며 실제적인 수준에서 실제로 일어나고있는 것을 파헤쳐 야합니다. 나는 정말로 어떤 대답도 적절하게하지 못한다고 생각합니다. 그래서 여기에 제 시도가 있습니다.

    클래스와 객체가 무엇인지에 대해 이야기하면서 시작하겠습니다.

    그렇다면 수업은 무엇입니까? 많은 사람들이 그것을 청사진이나 물체의 템플릿으로 정의합니다. 사실, 여기 PHP에서 클래스에 대해 더 많이 읽을 수 있습니다. 그리고 그것은 어느 정도까지는 그것이 실제로 무엇인지입니다. 수업을 살펴 ​​보겠습니다.

    class Person {
        public $name = 'my name';
        public function sayHello() {
            echo "Hello";
        }
    }
    

    여러분이 알 수 있듯이, 클래스에는 $ name이라는 속성과 sayHello ()라는 메서드 (함수)가 있습니다.

    클래스가 정적 인 구조임을 유의하는 것이 중요합니다. Person 클래스는 일단 정의되면, 항상 여러분이 보게되는 모든 곳에서 동일하다는 것을 의미합니다.

    반면에 객체는 클래스의 인스턴스라고 불리는 것입니다. 그 의미는 클래스의 "청사진"을 가져 와서 동적 복사본을 만드는 데 사용한다는 것입니다. 이 복사본은 이제 저장된 변수에 구체적으로 묶여 있습니다. 따라서 인스턴스에 대한 변경 사항은 해당 인스턴스에 대해 로컬입니다.

    $bob = new Person;
    $adam = new Person;
    $bob->name = 'Bob';
    echo $adam->name; // "my name"
    

    new 연산자를 사용하여 클래스의 새 인스턴스를 만듭니다.

    따라서 Class는 전역 구조이고 Object는 지역 구조라고합니다. 그 우스꽝 스러움에 대해 걱정할 필요는 없습니다. 우리는 약간의 이야기를 할 것입니다.

    우리가 이야기해야 할 또 하나의 것은 인스턴스가 특정 클래스의 인스턴스인지 검사 할 수 있다는 것이다. $ bob instanceof $ bob 인스턴스가 Person 클래스 나 Person의 자식을 사용하여 만들어진 경우 boolean을 반환하는 Person.

    클래스가 실제로 포함하고있는 것을 조금 파헤 치자. 수업에는 5 가지 유형의 '사물'이 있습니다.

    그래서 기본적으로, 우리는 클래스와 객체 컨테이너에 정보를 저장합니다. 정보가 공유되어 있는지 (따라서 정적인지 아닌지) 동적인지를 식별하는 정적에 대한 "힌트"를 사용합니다.

    메소드 내부에서 객체의 인스턴스는 $ this 변수로 표현됩니다. 해당 개체의 현재 상태가 있으며 속성을 변경 (변경)하면 해당 인스턴스가 변경됩니다 (다른 개체는 변경되지 않음).

    메서드가 정적으로 호출되면 $ this 변수가 정의되지 않습니다. 정적 호출과 연결된 인스턴스가 없기 때문입니다.

    여기서 흥미로운 점은 정적 호출이 이루어지는 방법입니다. 이제 우리가 국가에 어떻게 접근하는지 이야기합시다.

    이제 우리는 그 상태를 저장 했으므로 그 상태에 액세스해야합니다. 이것은 약간 까다로울 수 있습니다. (예를 들어, 보통의 함수 호출이나 글로벌 스코프에서) 인스턴스와 클래스의 바깥 쪽과 인스턴스의 안쪽에서 두 개의 관점으로 나누겠습니다. / 클래스 (개체의 메서드 내에서).

    인스턴스 / 클래스 외부에서 우리 규칙은 매우 간단하고 예측 가능합니다. 우리는 두 개의 연산자를 가지고 있으며 각각 인스턴스 나 클래스를 정적으로 처리하는지 여부를 알려줍니다.

    따라서 $ this는 정적 호출에 정의되어 있지 않습니다.

    상황이 조금 바뀝니다. 동일한 연산자가 사용되지만 의미가 크게 흐려집니다.

    object-operator ->는 여전히 객체의 인스턴스 상태를 호출하는 데 사용됩니다.

    class Foo {
        public $a = 1;
        public function bar() {
            return $this->a;
        }
    }
    

    object-operator : $ foo-> bar ()를 사용하여 $ foo (Foo의 인스턴스)에 bar () 메소드를 호출하면 인스턴스의 버전이 $ a가됩니다.

    그것이 우리가 기대하는 방식입니다.

    :: 연산자의 의미는 변경됩니다. 현재 함수에 대한 호출의 컨텍스트에 따라 다릅니다.

    이해가 되니? 그렇게 생각하지 않았다. 혼란 스럽네.

    클래스 이름을 사용하여 모든 것을 묶는 것이 다소 지저분하기 때문에 PHP는 범위를 쉽게 해석 할 수 있도록 3 가지 기본 "바로 가기"키워드를 제공합니다.

    이것을 이해하는 가장 쉬운 방법은 몇 가지 예를 살펴 보는 것입니다. 수업을 선택하겠습니다.

    class Person {
        public static $number = 0;
        public $id = 0;
        public function __construct() {
            self::$number++;
            $this->id = self::$number;
        }
        public $name = "";
        public function getName() {
            return $this->name;
        }
        public function getId() {
            return $this->id;
        }
    }
    
    class Child extends Person {
        public $age = 0;
        public function __construct($age) {
            $this->age = $age;
            parent::__construct();
        }
        public function getName() {
            return 'child: ' . parent::getName();
        }
    }
    

    자, 우리는 또한 상속을 여기에서보고 있습니다. 잠시 동안 이것이 나쁜 객체 모델이라는 것을 무시하십시오. 그러나 이것으로 놀 때 어떤 일이 일어나는지 보도록하겠습니다 :

    $bob = new Person;
    $bob->name = "Bob";
    $adam = new Person;
    $adam->name = "Adam";
    $billy = new Child;
    $billy->name = "Billy";
    var_dump($bob->getId()); // 1
    var_dump($adam->getId()); // 2
    var_dump($billy->getId()); // 3
    

    따라서 ID 카운터는 인스턴스와 자식 모두에서 공유됩니다 (자체를 사용하기 때문에 자체에 액세스합니다. 정적을 사용하면 하위 클래스에서 재정의 할 수 있습니다).

    var_dump($bob->getName()); // Bob
    var_dump($adam->getName()); // Adam
    var_dump($billy->getName()); // child: Billy
    

    우리는 매번 Person :: getName () 인스턴스 메소드를 실행하고있다. 그러나 우리는 부모 :: getName ()을 사용하여 케이스 중 하나에서 수행합니다 (자식 케이스). 이것이이 접근법을 강력하게 만드는 이유입니다.

    호출 컨텍스트는 인스턴스가 사용되는지 여부를 결정합니다. 따라서:

    class Foo {
        public function isFoo() {
            return $this instanceof Foo;
        }
    }
    

    항상 사실이 아닙니다.

    class Bar {
        public function doSomething() {
            return Foo::isFoo();
        }
    }
    $b = new Bar;
    var_dump($b->doSomething()); // bool(false)
    

    이제 정말 이상합니다. 우리는 다른 클래스를 호출하지만 Foo :: isFoo () 메서드에 전달되는 $ this는 $ bar의 인스턴스입니다.

    이로 인해 모든 종류의 버그와 개념적인 WTF-ery가 발생할 수 있습니다. 그래서 나는 세 가지 가상 "short-cut"키워드 (static, self, parent)를 제외하고 인스턴스 메소드 내에서 :: 연산자를 피하는 것이 좋습니다.

    정적 메서드 및 속성은 모든 사람이 공유합니다. 이는 기본적으로 전역 변수가됩니다. 세계화와 관련된 모든 문제들. 따라서 진정한 글로벌 환경에 익숙하지 않다면 정적 메서드 / 속성에 정보를 저장하는 것을 주저하게 될 것입니다.

    일반적으로 자기 대신에 정적을 사용하여 Late-Static-Binding으로 알려진 것을 사용하고자합니다. 하지만 그들은 똑같은 것이 아니므로 "항상 자기보다는 정적으로 사용하는 것이 정말 시력이 좋지 않습니다. 대신 아이 클래스가 그것을 재정의 할 수있게 만들고 싶으면 생각하고 싶은 생각을 멈추고 생각하십시오. 정적 해결 된 호출.

    너무 나쁜, 돌아가서 그것을 읽으십시오. 너무 길 수도 있지만 복잡한 주제이기 때문에 오래되었습니다.

    알았어 괜찮아. 즉, self는 클래스 내에서 현재 클래스 이름을 참조하는 데 사용됩니다. 여기서 $ this는 현재 객체 인스턴스를 나타냅니다. self는 복사 / 붙여 넣기 단축키입니다. 클래스 이름으로 안전하게 바꿀 수 있으며 제대로 작동합니다. 하지만 $ this는 동적 변수이므로 미리 결정할 수 없습니다 (클래스가 아닐 수도 있습니다).

    object-operator가 사용되면 (->), 인스턴스를 처리한다는 것을 항상 알게됩니다. scope-resolution-operator가 사용되는 경우 (: :), 컨텍스트에 대한 자세한 정보가 필요합니다 (우리는 이미 객체 - 컨텍스트에 있습니까? 객체 밖에 있습니까?).

  5. ==============================

    5.

    self ($ self가 아님)는 클래스의 유형을 말하며 $ this는 클래스의 현재 인스턴스를 나타냅니다. self는 정적 멤버 함수에 사용되어 정적 멤버 변수에 액세스 할 수 있도록합니다. $ this는 정적이 아닌 멤버 함수에서 사용되며 멤버 함수가 호출 된 클래스의 인스턴스에 대한 참조입니다.

    이것은 객체이기 때문에 다음과 같이 사용합니다 : $ this-> member

    self는 객체가 아니기 때문에 기본적으로 현재 클래스를 자동으로 참조하는 유형이며 self :: member와 같이 사용합니다.

  6. ==============================

    6.

    $ this->는 클래스의 변수 (멤버 변수) 또는 메소드의 특정 인스턴스를 참조하는 데 사용됩니다.

    Example: 
    $derek = new Person();
    

    $ derek는 이제 Person의 특정 인스턴스입니다. 모든 Person에는 first_name과 last_name이 있지만 $ derek에는 특정 first_name과 last_name이 있습니다 (Derek Martin). $ derek 인스턴스 안에서 $ this-> first_name과 $ this-> last_name을 참조 할 수 있습니다.

    ClassName ::은 해당 유형의 클래스 및 정적 변수 인 정적 메서드를 나타내는 데 사용됩니다. 도움이된다면 "정적"이라는 단어를 "공유 된"단어로 대체 할 수 있습니다. 공유되므로 특정 인스턴스 (공유되지 않음)를 참조하는 $ this를 참조 할 수 없습니다. 정적 변수 (static $ db_connection)는 객체 유형의 모든 인스턴스간에 공유 될 수 있습니다. 예를 들어 모든 데이터베이스 개체는 단일 연결 (정적 $ 연결)을 공유합니다.

    정적 변수 예제 : 우리는 하나의 멤버 변수를 가진 데이터베이스 클래스를 가지고있다 : static $ num_connections; 자, 생성자에 넣어 :

    function __construct()
    {
        if(!isset $num_connections || $num_connections==null)
        {
            $num_connections=0;
        }
        else
        {
            $num_connections++;
        }
    }
    

    객체에 생성자가있는 것처럼 소멸자도 있습니다. 객체가 죽거나 설정되지 않은 경우 실행됩니다.

    function __destruct()
    {
        $num_connections--;
    }
    

    새 인스턴스를 만들 때마다 연결 카운터가 하나씩 증가합니다. 인스턴스를 파괴하거나 사용할 때마다 연결 카운터가 하나씩 감소합니다. 이 방법으로 우리는 다음과 함께 사용중인 데이터베이스 객체의 인스턴스 수를 모니터링 할 수 있습니다.

    echo DB::num_connections;
    

    $ num_connections는 정적 (공유)이기 때문에 활성 데이터베이스 객체의 총 수를 반영합니다. 이 기술이 데이터베이스 클래스의 모든 인스턴스간에 데이터베이스 연결을 공유하는 데 사용되는 것을 보았을 수 있습니다. 데이터베이스 연결을 만드는 데 오랜 시간이 걸리기 때문에이 작업이 필요합니다. 따라서 하나만 만들고 공유하는 것이 가장 좋습니다 (이 작업을 싱글 톤 패턴이라고합니다).

    정적 메소드 (예 : public static View :: format_phone_number ($ digits))는 해당 객체 중 하나를 처음 인스턴스화하지 않고 사용할 수 있습니다. 즉, 내부적으로 $ this를 참조하지 않습니다.

    정적 메서드 예제 :

    public static function prettyName($first_name, $last_name)
    {
        echo ucfirst($first_name).' '.ucfirst($last_name);
    }
    
    echo Person::prettyName($derek->first_name, $derek->last_name);
    

    보시다시피, public static function prettyName은 객체에 대해 아무것도 모릅니다. 그것은 객체의 일부가 아닌 정상적인 함수처럼 전달하는 매개 변수로 작업하는 것입니다. 왜 우리가 그것을 대상의 일부로 가질 수 없다면, 왜 귀찮게합니까?

    본인:: 참조하려는 정적 메서드가있는 개체 외부에서 코딩하는 경우에는 개체의 이름 View :: format_phone_number ($ phone_number)를 사용하여 호출해야합니다. 참조하려는 정적 메소드가있는 객체 내부에서 코딩하는 경우 객체의 이름 View :: format_phone_number ($ pn)를 사용하거나 self :: format_phone_number ($ pn) 단축키를 사용할 수 있습니다

    정적 변수에서도 마찬가지입니다. 예 : View :: templates_path 대 self :: templates_path

    DB 클래스 내부에서 다른 객체의 정적 메소드를 참조하는 경우 객체의 이름을 사용합니다. 예 : Session :: getUsersOnline ();

    그러나 DB 클래스가 자체 정적 변수를 참조하려는 경우에는 self라고 말합니다. 예 : self :: connection;

    호프는 물건을 정리하는 데 도움이 :)

  7. ==============================

    7.

    이 블로그 게시물에서 :

  8. ==============================

    8.

    PHP에서는 self 키워드를 사용하여 정적 속성 및 메서드에 액세스합니다.

    문제는 method ()가 static으로 선언되었는지 여부에 관계없이 $ this-> method ()를 self :: method ()로 바꿀 수 있다는 것입니다. 그래서 어느 것을 사용해야합니까?

    다음 코드를 고려하십시오.

    class ParentClass {
        function test() {
            self::who();    // will output 'parent'
            $this->who();   // will output 'child'
        }
    
        function who() {
            echo 'parent';
        }
    }
    
    class ChildClass extends ParentClass {
        function who() {
            echo 'child';
        }
    }
    
    $obj = new ChildClass();
    $obj->test();
    

    이 예제에서 self :: who ()는 항상 'parent'를 출력하지만 $ this-> who ()는 객체의 클래스에 따라 다릅니다.

    이제 우리는 자기가 호출되는 클래스를 참조하는 반면 $ this는 현재 객체의 클래스를 참조하는 것을 볼 수 있습니다.

    따라서 $ this가 사용 가능하지 않거나 자손 클래스가 현재 메소드를 겹쳐 쓰도록 허용하지 않으려는 경우에만 self를 사용해야합니다.

  9. ==============================

    9.

    클래스 정의에서 $ this는 현재 객체를 참조하고 self는 현재 클래스를 참조합니다.

    self를 사용하여 클래스 요소를 참조하고 $ this를 사용하여 object 요소를 참조해야합니다.

    self::STAT // refer to a constant value
    self::$stat // static variable
    $this->stat // refer to an object variable  
    
  10. ==============================

    10.

    <?php
    class X {
        private $non_static_member = 1;
        private static $static_member = 2;
    
        function __construct() {
            echo $this->non_static_member . ' '
               . self::$static_member;
        }
    }
    
    new X();
    ?> 
    
  11. ==============================

    11.

    http://www.php.net/manual/en/language.oop5.static.php에 따르면 $ self는 없습니다. 클래스의 정적 멤버를 참조하는 데 사용할 수있는 self (클래스)의 현재 인스턴스를 참조하기 위해 $ this 만 있습니다. 오브젝트 인스턴스와 클래스 간의 차이점이 여기에 작용합니다.

  12. ==============================

    12.

    여기서 공연에 관해 언급 한 사람이 아무도 없기 때문에 여기에 내가했던 작은 벤치 마크 (5.6)가 있습니다.

     Name     | Time    | Percent  
    ----------|---------|---------  
     $this->  | 0.99163 | 106.23%  
     self::   | 0.96912 | 103.82%  
     static:: | 0.93348 | 100%
    

    그 2 000 000 실행에 대한 결과이며, 여기에 내가 사용하는 코드입니다 :

    <?php
    
    require '../vendor/autoload.php';
    
    // My small class to do benchmarks
    // All it does is looping over every test x times and record the
    //   time it takes using `microtime(true)`
    // Then, the percentage is calculated, with 100% being the quickest
    // Times are being rouned for outputting only, not to calculate the percentages
    $b = new Tleb\Benchmark\Benchmark(2000000);
    
    class Foo
    {
        public function calling_this()
        {
            $this->called();
        }
    
        public function calling_self()
        {
            self::called();
        }
    
        public function calling_static()
        {
            static::called();
        }
    
        public static function called()
        {
        }
    }
    
    $b->add('$this->',  function () { $foo = new Foo; $foo->calling_this(); });
    $b->add('self::',   function () { $foo = new Foo; $foo->calling_self(); });
    $b->add('static::', function () { $foo = new Foo; $foo->calling_static(); });
    
    $b->run();
    
  13. ==============================

    13.

    self는 현재 클래스 (호출되는 클래스)를 참조합니다.

    $ this는 현재 객체를 참조합니다. 자기 대신 정적을 사용할 수 있습니다. 다음 예제를 참조하십시오.

        class ParentClass {
                function test() {
                        self::which();  // output 'parent'
                        $this->which(); // output 'child'
                }
    
                function which() {
                        echo 'parent';
                }
        }
    
        class ChildClass extends ParentClass {
                function which() {
                        echo 'child';
                }
        }
    
        $obj = new ChildClass();
        $obj->test();
    

    산출:       부모의      어린이

  14. ==============================

    14.

    className :: staticMember를 호출하여 클래스의 정적 멤버를 호출 할 수 있는지 여부는 질문과 다릅니다. 질문은 self :: classmember와 $ this-> classmember를 사용하는 것의 차이점입니다.

    예를 들어, 다음 예제는 모두 self :: 또는 $ this->

    class Person{
        private $name;
        private $address;
    
        public function __construct($new_name,$new_address){
            $this->name = $new_name;
            $this->address = $new_address;
        }
    }
    
    class Person{
        private $name;
        private $address;
        public function __construct($new_name,$new_address){
            self::$name = $new_name;
            self::$address = $new_address;
        }
    }
    
  15. ==============================

    15.

    오버로드를 보여주는 다음 예제를 참조하십시오.

    <?php
    
    class A {
    
        public static function newStaticClass()
        {
            return new static;
        }
    
        public static function newSelfClass()
        {
            return new self;
        }
    
        public function newThisClass()
        {
            return new $this;
        }
    }
    
    class B extends A
    {
        public function newParentClass()
        {
            return new parent;
        }
    }
    
    
    $b = new B;
    
    var_dump($b::newStaticClass()); // B
    var_dump($b::newSelfClass()); // A because self belongs to "A"
    var_dump($b->newThisClass()); // B
    var_dump($b->newParentClass()); // A
    
    
    class C extends B
    {
        public static function newSelfClass()
        {
            return new self;
        }
    }
    
    
    $c = new C;
    
    var_dump($c::newStaticClass()); // C
    var_dump($c::newSelfClass()); // C because self now points to "C" class
    var_dump($c->newThisClass()); // C
    var_dump($b->newParentClass()); // A because parent was defined *way back* in class "B"
    

    대부분의 경우 정적 또는 $ this를 사용하는 이유 인 현재 클래스를 참조하려고합니다. 그러나 확장 할 때와 상관없이 원래 클래스를 원하기 때문에 자아가 필요할 때가 있습니다. (매우, 아주 드물게)

  16. ==============================

    16.

    self가 :: 연산자와 함께 사용되면 현재 클래스를 참조하며 정적 및 비 정적 컨텍스트 모두에서 수행 할 수 있습니다. $ this는 객체 자체를 참조합니다. 또한 정적 메서드를 호출 할 때 $ this를 사용하는 것이 합법적입니다 (그러나 필드를 참조하지는 않음).

  17. ==============================

    17.

    $ this는 현재 클래스 객체를 참조하고, self는 현재 클래스 (Not 객체)를 참조합니다. 클래스는 객체의 청사진입니다. 그래서 당신은 클래스를 정의하지만 객체를 생성합니다.

    즉, 정적에 대해서는 self를 사용하고, 정적이 아닌 멤버 또는 메서드에 대해서는 this를 사용하십시오.

    또한 자식 / 부모 시나리오에서 self / parent는 주로 자식 및 부모 클래스 멤버와 메서드를 식별하는 데 사용됩니다.

  18. ==============================

    18.

    또한 $ this :: 아직 논의되지 않았기 때문에.

    정보 제공 목적으로 PHP 5.3에서 인스턴스화 된 객체를 처리하여 현재 범위 값을 얻는 대신 static ::을 사용하는 것과는 달리 $ this :: like를 대신 사용할 수 있습니다.

    http://ideone.com/7etRHy

    class Foo
    {
        const NAME = 'Foo';
    
        //Always Foo::NAME (Foo) due to self
        protected static $staticName = self::NAME;
    
        public function __construct()
        {
            echo $this::NAME;
        }
    
        public function getStaticName()
        {
           echo $this::$staticName;
        }
    }
    
    class Bar extends Foo
    {
        const NAME = 'FooBar';
    
        /**
         * override getStaticName to output Bar::NAME
         */
        public function getStaticName()
        {
            $this::$staticName = $this::NAME;
            parent::getStaticName();
        }
    }
    
    $foo = new Foo; //outputs Foo
    $bar = new Bar; //outputs FooBar
    $foo->getStaticName(); //outputs Foo
    $bar->getStaticName(); //outputs FooBar
    $foo->getStaticName(); //outputs FooBar
    

    위의 코드를 사용하는 것이 일반적이거나 권장되는 방법은 아니지만 간단하게 용도를 설명하는 것입니다. "알고 계셨습니까?" 원래의 포스터의 질문을 참조하십시오.

    또한 $ object :: CONSTANT의 사용법을 나타냅니다. 예를 들어 echo $ foo :: NAME; $ this :: NAME과 반대로;

  19. ==============================

    19.

    그 클래스의 객체 / 인스턴스를 생성하지 않고 클래스의 메소드를 호출하기 위해 self를 사용하십시오. 따라서 RAM을 절약하십시오 (때로는 그 목적을 위해 self를 사용합니다). 즉, 실제로 정적으로 메서드를 호출합니다. 객체 관점에서 사용하십시오.

  20. ==============================

    20.

    사례 1 : use self는 클래스 상수에 사용할 수 있습니다.

     class classA { 
         const FIXED_NUMBER = 4; 
         self::POUNDS_TO_KILOGRAMS
    }
    

    클래스 외부에서 호출하려면 classA :: POUNDS_TO_KILOGRAMS를 사용하여 상수에 액세스하십시오

    사례 2 : 정적 속성

    class classC {
         public function __construct() { 
         self::$_counter++; $this->num = self::$_counter;
       }
    }
    
  21. ==============================

    21.

    나는 같은 질문에 빠졌고 간단한 대답은 :

    정적 메서드 나 정적 특성을 사용할 때마다 클래스의 개체를 인스턴스화하지 않고 개체를 호출하려면 self ::를 사용해야합니다. 왜냐하면 $ this는 항상 개체를 만들 때 필요하기 때문입니다.

  22. ==============================

    22.

    php.net에 따르면 self, parent 및 static이라는 세 가지 특수 키워드가이 문맥에 있습니다. 클래스 정의 내부에서 속성이나 메서드에 액세스하는 데 사용됩니다.

    반면에 $ this는 클래스에 액세스 할 수있는 한 모든 클래스의 인스턴스와 메소드를 호출하는 데 사용됩니다.

  23. from https://stackoverflow.com/questions/151969/when-to-use-self-over-this by cc-by-sa and MIT lisence