1. 程式人生 > >tp5 魔法函式

tp5 魔法函式

在thinkphp5中,使用了大量的魔法函式。
為了讓大家在學習thinkphp5時,能夠更清楚的明白thinkphp5的原理,我們使用以下示例來學習一下__set()__get()魔法函式。

**注意:**是__不是_

__get()

<?php
class Test
{
    public $hi = 'hi';
}

$Test = new Test();
echo $Test->hi;

測試結果很明顯,輸出了公有屬性的值。

如果將$hi改為私有或是保護型別時就會報錯:

<?php
class Test
{
    private $hi = 'hi';
}

$Test = new Test();
echo $Test->hi;

我們知道,從安全的角度出發,類中所有的屬性我們都會宣告為privateprotected。所以,如果想輸出一個私有屬性,往往都是按下面的方法進行處理的。

<?php
class Test
{
    private $hi = 'hi';

    public function getHi()
    {
        return $this->hi;
    }
}

$Test = new Test();
echo $Test->getHi();

測試結果表明:同樣輸出了hi的值

有了魔法函式後,想實現相同的功能,我們還可以這樣寫:

<?php
class Test
{
    private $hi = 'hi yunzhi';
    public function __get($name)
    {
        echo $name . '<br />';
        echo $this->hi;
    }
}

$Test = new Test();
echo $Test->hi;
我們看到,當呼叫hi這個屬性時,由於並不存在可以直接供我們呼叫的hi屬性(只有public型別的屬性才能被直接呼叫),那麼就自動執行了__get()方法,並將$name的值置為hi, 然後執行後續的程式碼。

thinkphp5在獲取一個物件後,可以直接將資料表中的欄位值做為屬性輸出,就是利用的這個方法。

示例程式碼如下:

<?php
class Test
{
    private $data = array(
        'name' => '張三',
        'sex'   => '0'
        );

    public function __get($name)
    {
        // 校驗在$this->data中是否存在這個健值。
        // 如果存在,即返回,如果不存在,則返回$this->data整個陣列。
        if (array_key_exists($name, $this->data)) {
            return $this->data[$name];
        } else {
            return $this->data;
        }
    }
}

$Test = new Test();
echo $Test->name;
echo $Test->sex;
var_dump($Test->hello);

注意:此時最後一行hello不管換成任何屬性(字母),都可以輸出陣列內容

__set()

有了剛剛的__get(),__set()理解起來也就簡單了。在thinkphp5中,我們在進行資料的新增或更新時,會直接對一個物件的屬性進行賦值。我們當然知道,在沒有接觸到魔法函式以前,如果這個類中並不存在這個屬性,或是這個屬性不是public型別,那麼我們直接賦值時就會發生一個異常,__set()就是用來解決這些問題的。

<?php
class Test
{
    private $data = array();

    public function __get($name)
    {
        // 校驗在$this->data中是否存在這個健值。
        // 如果存在,即返回,如果不存在,則提示該欄位不存在。
        if (array_key_exists($name, $this->data)) {
            return $this->data[$name];
        } else {
            return '欄位' . $name . '不存在';
        }
    }

    public function __set($name, $value)
    {
        echo '$name is ' . $name . ', $value is ' . $value . '<br />';
        $this->data[$name] = $value;
    }
}

$Test = new Test();
$Test->name = '李四';
$Test->sex = '1';
echo $Test->name . '<br />';
echo $Test->sex;

//並不存在hello欄位
echo $Test->hello;