首頁  >  文章  >  後端開發  >  php類別和物件--重載

php類別和物件--重載

伊谢尔伦
伊谢尔伦原創
2016-11-23 14:03:22902瀏覽

PHP所提供的"重載"(overloading)是指動態地"建立"類別屬性和方法。我們是透過魔術方法(magic methods)來實現的。

當呼叫目前環境下未定義或不可見的類別屬性或方法時,重載方法會被呼叫。

所有的重載方法都必須宣告為 public。

注意:

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 變數的值。

屬性重載只能在物件中進行。在靜態方法中,這些魔術方法將不會被呼叫。所以這些方法都不能被 宣告為 static。從 PHP 5.3.0 起, 將這些魔術方法定義為 static 會產生一個警告。

注意:

因為 PHP 處理賦值運算的方式,__set() 的回傳值會被忽略。類似的, 在下面這樣的鍊式賦值中,__get() 不會被調用:

$a = $obj->b = 8;

注意:

在除 isset() 外的其它語言結構中無法使用重載的屬性,這表示當對一個重載的屬性使用 empty() 時,重載魔術方法將不會被呼叫。

為避開此限制,必須將重載屬性賦值到本地變數再使用 empty()。

Example #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;

輸出結果:

Setting 'a' to '1'

Is 'a' set?

bool(true)

Unsetting 'a'

1

Let's experiment with the private property named 'hidden':

) iniv. ...

2

Privates not visible outside of class,so __get() is used...

Getting 'hidden'

方法重載

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

在物件中使用一個不可存取方法時,__call(__在物件中) 會被呼叫。

用靜態方式中呼叫一個不可存取方法時,__callStatic() 會被呼叫。

$name 參數是要呼叫的方法名稱。 $arguments 參數是一個枚舉數組,包含著要傳遞給方法 $name 的參數。

Example #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;);

輸出結果:

Calling object method 'runTest'

Calling object method 'runTest'

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn