>  기사  >  백엔드 개발  >  PHP 클래스 및 객체--오버로딩

PHP 클래스 및 객체--오버로딩

伊谢尔伦
伊谢尔伦원래의
2016-11-23 14:03:22908검색

PHP에서 제공하는 "오버로딩"은 클래스 속성과 메서드를 동적으로 "생성"하는 것을 의미합니다. 우리는 마법의 방법을 통해 이를 수행합니다.

현재 환경에서 정의되지 않았거나 보이지 않는 클래스 속성이나 메서드를 호출할 때 오버로드된 메서드가 호출됩니다.

오버로드된 모든 메서드는 공개로 선언되어야 합니다.

참고:

1) 이러한 매직 메소드의 매개변수는 참조로 전달될 수 없습니다.

2) PHP의 "오버로딩"은 대부분의 다른 객체 지향 언어와 다릅니다. 전통적인 "오버로딩"은 동일한 이름을 가진 여러 클래스 메서드를 제공하는 데 사용되지만 각 메서드의 매개 변수 유형과 개수는 다릅니다.

속성 오버로딩

public void__set(string$name, mixed$value)
publicmixed__get(string$name)
publicbool__isset(string$name)
publicvoid__unset(string$name)

액세스할 수 없는 속성에 값을 할당하면 __set()가 호출됩니다.

액세스할 수 없는 속성의 값을 읽을 때 __get()이 호출됩니다.

액세스할 수 없는 속성에 대해 isset() 또는 empty()가 호출되면 __isset()가 호출됩니다.

액세스할 수 없는 속성에 대해 unset()이 호출되면 __unset()이 호출됩니다.

$name 매개변수는 연산할 변수의 이름을 나타냅니다. __set() 메서드의 $value 매개 변수는 $name 변수의 값을 지정합니다.

속성 오버로드는 객체에서만 수행할 수 있습니다. 정적 메서드에서는 이러한 매직 메서드가 호출되지 않습니다. 따라서 이러한 메서드 중 어느 것도 정적으로 선언할 수 없습니다. PHP 5.3.0부터 이러한 매직 메서드를 정적으로 정의하면 경고가 생성됩니다.

참고:

PHP가 할당 작업을 처리하는 방식으로 인해 __set()의 반환 값은 무시됩니다. 마찬가지로 다음 체인 할당에서는 __get()이 호출되지 않습니다.

$a = $obj->b = 8;

참고:

오버로드된 속성 isset()을 제외한 다른 언어 구성에서는 사용할 수 없습니다. 즉, 오버로드된 속성에 empty()를 사용할 때 오버로드된 매직 메서드가 호출되지 않습니다.

이러한 제한을 피하려면 오버로드된 속성을 지역 변수에 할당한 다음 비어 있음()을 사용해야 합니다.

예제 #1 속성 오버로드에 __get(), __set(), __isset() 및 __unset() 사용

class PropertyTest{
    /*被重载的数据保存在此*/
    private $data = array();
    /*重载不能被用在已经定义的属性*/
    public $declared = 1;
    /*只有从类外部访问这个属性时,重载才会发生*/
    private $hidden = 2;
    public function __set($name,$value)
    {
        echo "Setting &#39;$name&#39; to &#39;$value&#39;<br>";
        $this->data[$name] = $value;
    }
    public function __get($name)
    {
        echo "Getting &#39;$name&#39;<br>";
        if(array_key_exists($name,$this->data)){
            return $this->data[$name];
        }
        $trace = debug_backtrace();
        trigger_error(&#39;未知属性 via __get():&#39;.$name.&#39; in &#39;.$trace[0][&#39;file&#39;].&#39; on line &#39;.$trace[0][&#39;line&#39;],
            E_USER_NOTICE);  
        return null;
    }
    /*PHP5.1.0之后的版本*/
    public function __isset($name){
        echo "Is &#39;$name&#39; set?<br>";
        return isset($this->data[$name]);
    }
    /*PHP5.1.0之后的版本*/
    public function __unset($name){
        echo "Unsetting &#39;$name&#39;<br>";
        unset($this->data[$name]);
    }
    /*非魔术方法*/
    public function getHidden(){
        return $this->hidden;
    }
}
echo &#39;<pre class="brush:php;toolbar:false">&#39;;
$obj = new PropertyTest;
$obj->a = 1;
echo $obj->a.&#39;<br>&#39;;
var_dump(isset($obj->a));
unset($obj->a);
echo &#39;<br>&#39;;
echo $obj->declared.&#39;<br>&#39;;
echo "Let&#39;s experiment with the private property named &#39;hidden&#39;:<br>";
echo "Privates are visible inside the class,so __set() not used...<br>";
echo $obj->getHidden().&#39;<br>&#39;;
echo "Privates not visible outside of class,so __get() is used...<br>";
echo $obj->hidden;

출력 결과:

'a' 설정 '1'로

'a' 가져오기

1

'a'가 설정되어 있나요?

bool(true)
'a'를 설정하지 않음

1

'hidden'이라는 개인 속성을 실험해 보겠습니다.

개인 속성은 클래스 내부에 표시되므로 __set()는 사용되지 않습니다...

2

Private는 클래스 외부에서는 볼 수 없으므로 __get()을 사용합니다...

'숨김' 가져오기

메서드 오버로딩

public mixed __call ( string$name , array$arguments )
public static mixed __callStatic ( string$name , array$arguments )

객체에서 액세스할 수 없는 메서드가 호출되면 __call()이 호출됩니다.

정적 모드에서 액세스할 수 없는 메서드를 호출하면 __callStatic()이 호출됩니다.

$name 매개변수는 호출할 메소드의 이름입니다. $arguments 매개변수는 $name 메소드에 전달될 매개변수를 포함하는 열거형 배열입니다.

예제 #2 __call() 및 __callStatic()을 사용하여 메서드 오버로드

class MethodTest
{
    public function __call($name,$arguments)
    {
        //注意:$name的值区分大小写
        echo "Calling object method &#39;$name&#39; ".implode(&#39;,&#39;,$argument).&#39;<br>&#39;;
    }
    //PHP5.3.0之后的版本
    public static function __callStatic($name,$arguments)
    {
        //注意:$name的值区分大小写
        echo "Calling static method &#39;$name&#39; ".implode(&#39;,&#39;,$argument).&#39;<br>&#39;;
    }
}
$obj = new MethodTest;
$obj -> runTest(&#39;in object context&#39;);
MethodTest::runTest(&#39;in static context&#39;);

출력 결과:

객체 메서드 'runTest' 호출

객체 메소드 'runTest' 호출


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