>php教程 >php手册 >1.2 매직 메소드와 지연된 정적 바인딩

1.2 매직 메소드와 지연된 정적 바인딩

WBOY
WBOY원래의
2016-08-23 09:03:381149검색

1. 마법의 방법:

1.__get,__set

 __get: 액세스할 수 없는 속성을 ​​가져올 때 트리거됩니다(액세스할 수 없다는 것은 속성이 존재하지 않거나 액세스 권한이 없음을 의미합니다 )

__set: 액세스할 수 없는 속성에 값을 할당할 때 트리거됩니다.

 2.__isset,__unset

__isset: isset() 함수를 사용하여 액세스할 수 없는 속성이 결정될 때 트리거됩니다.

__unset: unset() 함수를 사용하여 액세스할 수 없는 속성을 조작할 때 트리거됩니다.

 3.__call,__callStatic

__call: 액세스할 수 없는 메서드가 호출될 때 트리거됩니다.

__callStatic: 액세스할 수 없는 정적 메서드가 호출될 때 트리거됩니다.

4.__construct,__destruct

__construct: 객체를 초기화할 때 트리거됩니다.

__destruct: 객체가 파괴되거나 스크립트가 실행될 때 트리거됩니다.

5.__자동 로드

__autoload: 액세스할 수 없는 클래스가 사용될 때 트리거됩니다.

 6.__클론

__clone: ​​​​객체가 복제될 때 트리거됩니다.

7.__자고__자고

__sleep: 직렬화가 사용될 때 트리거됨

__wakeup: unserialize를 사용할 때 트리거됩니다.

8.__toString,__invoke

__toString: 객체가 문자열로 작동할 때 트리거됩니다. 예를 들어 $obj가 객체인 경우 echo $obj는 __toString

을 트리거합니다.

__invoke: 객체가 함수로 사용될 때 트리거됩니다. $obj가 객체인 경우 $obj()는 __invoke를 트리거합니다

2. 지연된 정적 바인딩

개념은 제쳐두고 예를 살펴보고 이해하세요.

지연된 정적 바인딩은 처음에 어떻게 나타났나요? 다음 예를 참조하세요.

class A{<br>}<br>class B extends A{<br>    public static function out(){<br>        return new self();<br>    }<br>}<br>class C extends A{<br>    public static function out(){<br>        return new self();<br>    }<br>}<br>var_dump(B::out());//结果是object(B)#1 (0) { }<br>var_dump(C::out());//结果是object(C)#1 (0) { }<br>然后我们将子类中相同的代码抽取到父类class A中,变成:
class A{<br>    public static function out(){<br>        return new self();<br>    }<br>}<br>class B extends A{<br>}<br>class C extends A{<br>}<br>var_dump(B::out());//结果是object(A)#1 (0) { }<br>var_dump(C::out());//结果是object(A)#1 (0) { }<br>这个结果显然不是我们想要的,这里的问题主要是因为self指代的是它所在的类.这里self在类A里面,所以返回的永远是类A的对象,<br>而我们想要的是让out()方法返回调用它的类的对象而不是它所在的类的对象.怎么办?<br>此时我们马上可以想到$this可以代表调用它的对象,但是out()是一个静态方法,里面是不能出现$this的,怎么办?<br>用static.它也代表调用它的对象如:
class A{<br>    public static function out(){<br>        return new static();<br>    }<br>}<br>class B extends A{<br>}<br>class C extends A{<br>}<br>var_dump(B::out());//结果是object(B)#1 (0) { }<br>var_dump(C::out());//结果是object(C)#1 (0) { }<br>这样就好了.这就是延迟静态绑定.<br><br>在看下面的例子:

왜 이런 결과가 나온 걸까요? 분석해 보겠습니다.

먼저 객체 c는 get() 메소드를 호출했지만 C 클래스에는 없으므로 B 클래스에서 찾아서 찾은 다음 get 메소드를 실행합니다.

A::foo()를 먼저 실행합니다. 클래스 A는 자신의 foo()를 직접 호출하고 `fooA`를 출력한 다음 호출합니다. 분명히 여기에서 static::out()을 호출하는 것은 클래스 A입니다. 출력 클래스 이름도 A입니다. (여기서는 클래스 A에 초점을 맞춥니다)

그런 다음 parent::foo()를 실행합니다. 여기서는 클래스 A의 foo()가 실행되고 `fooA`가 출력된 다음 static::out()이 실행됩니다. 이번에는 정적 호출자가 클래스 A가 아니라 클래스 C입니다. 왜냐하면 parent는 부모 클래스를 나타내지만 특정 클래스를 나타내지는 않기 때문입니다(여기서는 부모 클래스가 누구인지에 관계없이 부모 클래스의 메서드에 중점을 둡니다).

그런 다음 self::foo()를 실행합니다. self는 자신이 속한 클래스(클래스 B)를 나타냅니다. 상위 클래스에서 찾지 않고 먼저 foo()를 실행하므로 `fooA`를 출력한 다음 static을 실행합니다. :out()도 같은 이유로 여기에 사용된 static은 클래스 A가 아닌 클래스 C입니다. self는 클래스 B를 나타내지만 self는 특정 클래스를 나타낼 수 없습니다.

간단히 말하면: 객체 c가 get()-->A::foo()를 실행하기 시작합니다. 이때 체인이 끊어지고 다음과 같이 됩니다. 클래스 A에서 직접 foo()를 호출하면 객체 c와는 아무런 관련이 없습니다. 물론 여기서 static은 클래스 A를 나타냅니다.

다음으로, 클래스 A의 객체 c-->parent::foo()--> foo()-->static::out() 퉁명스럽게 말하면 여기서 parent는 포인팅 함수입니다. 즉, 누구의 foo() 메소드가 실행되는지를 보면 객체 c가 클래스 A의 foo 메소드를 호출한다는 것을 알 수 있습니다. 그러면 foo의 static은 클래스 C를 나타냅니다.

마지막으로, 클래스 A의 객체 c-->self::foo()-->foo()-->static::out() 위와 동일합니다. 여기 self에도 포인팅 기능이 있습니다. , 그러나 우리는 마침내 클래스 A에 도달합니다. 객체 c가 클래스 A의 foo 메소드를 호출한다는 것을 이해할 수 있습니다. 그러면 foo의 static은 클래스 C를 나타냅니다


<br><br>
성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.