PHP 사후 정적 바인딩의 정의 및 사용 예에 ​​대한 자세한 설명

伊谢尔伦
풀어 주다: 2023-03-14 09:58:02
원래의
1519명이 탐색했습니다.

매뉴얼 원본: PHP 5.3.0부터 PHP에는 상속 범위에서 정적으로 호출된 클래스를 참조하는 데 사용되는 후기 정적 바인딩이라는 기능이 추가되었습니다. 후기 정적 바인딩의 작동 원리는 이전 "비전달 호출"에 클래스 이름을 저장하는 것입니다. 정적 메서드 호출을 수행할 때 클래스 이름은 명시적으로 지정된 이름입니다(일반적으로 :: 연산자의 왼쪽에 있음). 비정적 메서드 호출을 수행할 때는 개체가 속한 클래스입니다. 소위 "전달 호출"은 self::, parent::, static:: 및 전달_정적_call() 방식으로 이루어진 정적 호출을 의미합니다. get_called_class() 함수를 사용하여 호출된 메서드의 클래스 이름을 가져올 수 있으며 static::은 해당 범위를 가리킵니다.

이 기능은 언어 내부 관점에서 "후기 정적 바인딩"이라고 합니다. "후기 바인딩"은 static::이 더 이상 현재 메서드가 정의된 클래스로 확인되지 않고 실제 런타임에 계산된다는 의미입니다. 정적 메서드 호출에 사용할 수 있으므로(그러나 이에 국한되지는 않음) "정적 바인딩"이라고도 합니다.

self::의 제한 사항 현재 메서드가 정의된 클래스에 따라 현재 클래스에 대한 정적 참조에 self:: 또는 __CLASS__를 사용합니다.

예제 #1 self:: 사용법

<?php
class A {
public static function who() {
echo __CLASS__;
}
public static function test() {
self::who();
}
}
class B extends A {
public static function who() {
echo __CLASS__;
}
}
B::test();
?>
로그인 후 복사

위 루틴은 다음을 출력합니다.

A


후기 정적 바인딩 사용 후기 정적 바인딩은 런타임에 처음 호출되는 클래스를 나타내는 새 키워드를 도입하여 제한을 우회하기 위한 것입니다. 간단히 말해서, 이 키워드를 사용하면 위 예제에서 test()를 호출할 때 A 클래스 대신 B 클래스를 참조할 수 있습니다. 결국 새로운 키워드를 도입하지 않고 이미 예약된 정적 키워드를 사용하기로 결정되었습니다.

예제 #2 정적:: 간단한 사용법

<?php
class A {
public static function who() {
echo __CLASS__;
}
public static function test() {
static::who(); // 后期静态绑定从这里开始
}
}
class B extends A {
public static function who() {
echo __CLASS__;
}
}
B::test();
?>
로그인 후 복사

위 루틴은 다음을 출력합니다.

B


참고: 비정적 환경에서 호출된 클래스는 개체 인스턴스가 속한 클래스입니다. $this->는 동일한 범위에서 개인 메소드를 호출하려고 시도하므로 static::은 다른 결과를 제공할 수 있습니다. 또 다른 차이점은 static::은 정적 속성에만 사용할 수 있다는 것입니다.

예제 #3 static::

<?php
class A {
private function foo() {
echo "success!\n";
}
public function test() {
$this->foo();
static::foo();
}
}
class B extends A {
/* foo() will be copied to B, hence its scope will still be A and
* the call be successful */
}
class C extends A {
private function foo() {
/* original method is replaced; the scope of the new one is C */
}
}
$b = new B();
$b->test();
$c = new C();
$c->test(); //fails
?>
로그인 후 복사

사용 위 루틴은 다음을 출력합니다.

success!

success!
success!

치명적인 오류: 컨텍스트 'A'에서 개인 메서드 C::foo() 호출 9행의 /tmp/test.php

참고: 완전히 구문 분석된 정적 호출을 얻을 때까지 후기 정적 바인딩 구문 분석이 계속됩니다. 반면에 parent:: 또는 self::를 사용하여 정적으로 호출하면 호출 정보가 전달됩니다.


예제 #4 전달 및 전달되지 않는 호출

<?php
class A {
public static function foo() {
static::who();
}
public static function who() {
echo __CLASS__."\n";
}
}
class B extends A {
public static function test() {
A::foo();
parent::foo();
self::foo();
}
public static function who() {
echo __CLASS__."\n";
}
}
class C extends B {
public static function who() {
echo __CLASS__."\n";
}
}
C::test();
?>
로그인 후 복사

위 루틴은 다음을 출력합니다.

A

C
C

다음 예는 PHP의 후기를 기반으로 상속 범위에서 정적 호출을 참조하는 솔루션을 분석합니다. 정적 바인딩 함수 클래스.

먼저 다음 코드를 살펴보세요.

class Person
{
public static function status()
{
self::getStatus();
}
protected static function getStatus()
{
echo "Person is alive";
}
}
class Deceased extends Person
{
protected static function getStatus()
{
echo "Person is deceased";
}
}
Deceased::status(); //Person is alive
로그인 후 복사

분명히 결과는 우리가 예상한 것과 다릅니다. 이는 self::가 실행 중인 클래스가 아니라 정의된 클래스에 의존하기 때문입니다. 이 문제를 해결하려면 상속된 클래스에서 status() 메서드를 재정의할 수 있습니다. 더 나은 해결책은 PHP 5.3에 후기 정적 바인딩 기능이 추가된 것입니다.

코드는 다음과 같습니다.


class Person
{
public static function status()
{
static::getStatus();
}
protected static function getStatus()
{
echo "Person is alive";
}
}
class Deceased extends Person
{
protected static function getStatus()
{
echo "Person is deceased";
}
}
Deceased::status(); //Person is deceased
로그인 후 복사

static::은 더 이상 현재 클래스를 가리키지 않는다는 것을 알 수 있습니다. 실제로 런타임에 계산되어 최종 클래스의 모든 속성을 강제로 가져옵니다.

그러므로 더 이상 self::를 사용하지 않고 static::

을 사용하는 것이 좋습니다.

위 내용은 PHP 사후 정적 바인딩의 정의 및 사용 예에 ​​대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿