日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長(zhǎng)提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請(qǐng)做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會(huì)員:747

在 php 中,以雙下劃線(__)開始命名的方法被稱作 PHP 中的魔術(shù)方法,它們?cè)?PHP 中充當(dāng)很重要的角色。魔術(shù)方法包括:

16 個(gè) PHP 開發(fā)者必知必會(huì)的魔術(shù)方法

 

本文將使用一些實(shí)例展示 PHP 魔術(shù)方法的運(yùn)用。

 

1.__construct()

當(dāng)創(chuàng)建對(duì)象時(shí),PHP 類的構(gòu)造方法是第一個(gè)被調(diào)用的方法。每個(gè)類都有構(gòu)造方法。若你沒(méi)在類中明確聲明定義它,將會(huì)有一個(gè)默認(rèn)的無(wú)參類構(gòu)造方法存在,雖然它不會(huì)在類中定義出現(xiàn)。

 

1) 構(gòu)造方法的運(yùn)用

 

類的構(gòu)造方法通常用于執(zhí)行一些初始化任務(wù),諸如當(dāng)創(chuàng)建對(duì)象時(shí),為成員初始化賦值。

 

2) 類中構(gòu)造方法的聲明格式

function __constrct([parameter list]){
    方法具體實(shí)現(xiàn) //通常為成員變量初始賦值。
}

注意: 在多數(shù)類中僅可以聲明一個(gè)構(gòu)造方法。因?yàn)椋?PHP 不支持構(gòu)造方法重載。

下面是個(gè)完整的例子:

<?php
    class Person
    {                                                                     
            public $name;       
            public $age;       
            public $sex;       
        /**
         * 明確定義含參的構(gòu)造方法
         */                                                                                       
        public function __construct($name="", $sex="Male", $age=22)
        {     
            $this->name = $name;
            $this->sex = $sex;
            $this->age = $age;
        }
        /**
         * say 方法定義
         */
        public function say()
        {
            echo "Name:" . $this->name . ",Sex:" . $this->sex . ",Age:" . $this->age;
        }   
    }

無(wú)參創(chuàng)建 $Person1 對(duì)象。

$Person1 = new Person();
echo $Person1->say(); //顯示:Name:,Sex:Male,Age:22

使用一個(gè)參數(shù) "Jams" 調(diào)用創(chuàng)建 $Person2 對(duì)象。

$Person2 = new Person("Jams");
echo $Person2->say(); // 顯示: Name: Jams, Sex: Male, Age: 22

使用 3 個(gè)參數(shù)調(diào)用創(chuàng)建 $Person3 對(duì)象。

$Person3 = new Person ("Jack", "Male", 25);
echo $Person3->say(); // 顯示:Name: Jack, Sex: Male, Age: 25

__destruct()

析構(gòu)函數(shù)與構(gòu)造函數(shù)相反。

 

析構(gòu)函數(shù)允許你在銷毀對(duì)象之前執(zhí)行一些操作,例如關(guān)閉文件,清空結(jié)果集等等。

 

析構(gòu)函數(shù)是 PHP 5 引入的新功能。

 

析構(gòu)函數(shù)的聲明與構(gòu)造函數(shù)類似,以兩個(gè)下劃線開頭,名稱固定為 __destruct()。

 

析構(gòu)函數(shù)的聲明

function __destruct()
{    //method body
}

析構(gòu)函數(shù)不能帶參數(shù)

析構(gòu)函數(shù)的使用

析構(gòu)函數(shù)在類中一般不常見。它是類的可選部分,通常用于在類銷毀之前完成一些清理任務(wù)。

這是使用析構(gòu)函數(shù)的示例:

<?php
class Person{     
    public $name;         
    public $age;         
    public $sex;         
    public function __construct($name="", $sex="Male", $age=22)
    {   
        $this->name = $name;
        $this->sex  = $sex;
        $this->age  = $age;
    }
    /**
     * say method
     */
    public function say()
    {
        echo "Name:".$this->name.",Sex:".$this->sex.",Age:".$this->age;
    }   
    /**
     * declare a destructor method
     */
    public function __destruct()
    {
            echo "Well, my name is ".$this->name;
    }
}
$Person = new Person("John");
unset($Person); //destroy the object of $Person created above

輸出結(jié)果

Well, my name is John

__call()

該方法接受兩個(gè)參數(shù)。第一個(gè)參數(shù)為未定義的方法名稱,第二個(gè)參數(shù)則為傳入方法的參數(shù)構(gòu)成的數(shù)組

 

使用

function __call(string $function_name, array $arguments)
{    // method body
}

在程序中調(diào)用未定義方法時(shí), __call() 方法將被調(diào)用。

示例

<?php
class Person{                                 function say()
    {
           echo "Hello, world!<br>";
    }         function __call($funName, $arguments)
    {
          echo "The function you called:" . $funName . "(parameter:" ;  // Print the method's name that is not existed.
          print_r($arguments); // Print the parameter list of the method that is not existed.
          echo ")does not exist!!<br>n";                   
    }                                         
}
$Person = new Person();           
$Person->run("teacher"); // If the method which is not existed is called within the object, then the __call() method will be called automatically.
$Person->eat("John", "Apple");             
$Person->say();

顯示結(jié)果

The function you called: run (parameter: Array([0] => teacher)) does not exist!
The function you called: eat (parameter: Array([0] => John[1] => apple)) does not exist!
Hello world!

4. __callStatic()

當(dāng)在程序中調(diào)用未定義的靜態(tài)方法,__callStatic() 方法將會(huì)被自動(dòng)調(diào)用。

__callStatic() 的用法類似于 __call() 。下面舉個(gè)例子:

<?php
class Person{    function say()
    {        echo "Hello, world!<br>";
    }    public static function __callStatic($funName, $arguments)
    {        echo "The static method you called:" . $funName . "(parameter:" ;  // 打印出未定義的方法名。
        print_r($arguments); // 打印出未定義方法的參數(shù)列表。
        echo ")does not exist!<br>n";
    }}$Person = new Person();
$Person::run("teacher"); // 如果此項(xiàng)目?jī)?nèi)不存在的方法被調(diào)用了,那么 __callStatic() 方法將被自動(dòng)調(diào)用。
$Person::eat("John", "apple");
$Person->say();

執(zhí)行結(jié)果如下:

The static method you called: run (parameter: Array([0] => teacher)) does not exist!
The static method you called: eat (parameter: Array([0] => John[1] => apple)) does not exist!
Hello world!

__get()

當(dāng)你嘗試在外部訪問(wèn)對(duì)象的私有屬性時(shí),應(yīng)用程序?qū)伋霎惓2⒔Y(jié)束運(yùn)行。我們可以使用 __get 方法解決該問(wèn)題。該方法可以獲取從對(duì)象外部獲取私有屬性的值。舉例如下

<?php
class Person
{
    private $name;
    private $age;
    function __construct($name="", $age=1)
    {
        $this->name = $name;
        $this->age = $age;
    }
    public function __get($propertyName)
    {   
        if ($propertyName == "age") {
            if ($this->age > 30) {
                return $this->age - 10;
            } else {
                return $this->$propertyName;
            }
        } else {
            return $this->$propertyName;
        }
    }
}
$Person = new Person("John", 60);   // Instantiate the object with the Person class and assign initial values to the properties with the constructor.
echo "Name:" . $Person->name . "<br>";   // When the private property is accessed, the __get() method will be called automatically,so we can get the property value indirectly.
echo "Age:" . $Person->age . "<br>";    // The __get() method is called automatically,and it returns different values according to the object itself.

結(jié)果顯示如下

Name: John
Age: 50

6. __set()

set ($property,$value) 方法用于設(shè)置類的私有屬性。分配了未定義的屬性后,將觸發(fā) set () 方法,并且傳遞的參數(shù)是設(shè)置的屬性名稱和值。

面是演示代碼:

<?php
class Person{    private $name;
    private $age;
    public function __construct($name="",  $age=25)
    {
        $this->name = $name;
        $this->age  = $age;
    }    public function __set($property, $value) {
        if ($property=="age")
        {            if ($value > 150 || $value < 0) {
                return;
            }        }        $this->$property = $value;
    }    public function say(){
        echo "My name is ".$this->name.",I'm ".$this->age." years old";
    }}$Person=new Person("John", 25); //請(qǐng)注意,類初始化并為“name”和“age”分配初始值。
$Person->name = "Lili";     // "name" 屬性值被成功修改。如果沒(méi)有__set()方法,程序?qū)?bào)錯(cuò)。
$Person->age = 16; // "age"屬性修改成功。
$Person->age = 160; //160是無(wú)效值,因此修改失敗。
$Person->say();  //輸出:My name is Lili, I'm 16 years old。

代碼運(yùn)行結(jié)果:

My name is Lili, I'm 16 years old

7. __isset()

在使用__isset () 方法之前,讓我先解釋一下 isset () 方法的用法。isset () 方法主要用于確定是否設(shè)置了此變量。

 

如果在對(duì)象外部使用 isset () 方法,則有兩種情況:

 

如果該參數(shù)是公共屬性,則可以使用 isset () 方法確定是否設(shè)置了該屬性。

如果參數(shù)是私有屬性,則 isset () 方法將不起作用。

那么對(duì)于私有屬性,有什么辦法知道它是否被設(shè)置了嗎?當(dāng)然,只要在類中定義__isset () 方法,就可以在類外部使用 isset () 方法來(lái)確定是否設(shè)置了私有屬性。

 

當(dāng)在未定義或不可訪問(wèn)的屬性上調(diào)用 isset () 或 empty () 時(shí),將調(diào)用__isset () 方法。下面是一個(gè)例子:

<?php
class Person
{
    public $sex;
    private $name;
    private $age;
    public function __construct($name="",  $age=25, $sex='Male')
    {
        $this->name = $name;
        $this->age  = $age;
        $this->sex  = $sex;
    }
    /**
     * @param $content
     *
     * @return bool
     */
    public function __isset($content) {
        echo "The {$content} property is private,the __isset() method is called automatically.<br>";
        echo  isset($this->$content);
    }
}
$person = new Person("John", 25); // Initially assigned.
echo isset($person->sex),"<br>";
echo isset($person->name),"<br>";
echo isset($person->age),"<br>";

代碼運(yùn)行結(jié)果如下:

1
The name property is private,the __isset() method is called automatically.
1
The age property is private,the __isset() method is called automatically.
1

8. __unset()

與 isset () 方法類似,當(dāng)在未定義或不可訪問(wèn)的屬性上調(diào)用 unset () 方法時(shí),將調(diào)用 unset () 方法。下面是一個(gè)例子:

<?php
class Person
{
    public $sex;
    private $name;
    private $age;
    public function __construct($name="",  $age=25, $sex='Male')
    {
        $this->name = $name;
        $this->age  = $age;
        $this->sex  = $sex;
    }
    /**
     * @param $content
     *
     * @return bool
     */
    public function __unset($content) {
        echo "It is called automatically when we use the unset() method outside the class.<br>";
        echo  isset($this->$content);
    }
}
$person = new Person("John", 25); // Initially assigned.
unset($person->sex),"<br>";
unset($person->name),"<br>";
unset($person->age),"<br>";

代碼的運(yùn)行結(jié)果如下:

It is called automatically when we use the unset() method outside the class.
1
It is called automatically when we use the unset() method outside the class.
1

9. __sleep()

serialize () 方法將檢查類中是否有魔術(shù)方法__sleep ()。如果存在,將首先調(diào)用該方法,然后執(zhí)行序列化操作。

 

__sleep () 方法通常用于指定保存數(shù)據(jù)之前需要序列化的屬性。如果有一些非常大的對(duì)象不需要全部保存,那么您會(huì)發(fā)現(xiàn)此功能非常有用。

 

有關(guān)詳細(xì)信息,請(qǐng)參考以下代碼:

<?php
class Person
{
    public $sex;
    public $name;
    public $age;
    public function __construct($name="",  $age=25, $sex='Male')
    {
        $this->name = $name;
        $this->age  = $age;
        $this->sex  = $sex;
    }
    /**
     * @return array
     */
    public function __sleep() {
        echo "It is called when the serialize() method is called outside the class.<br>";
        $this->name = base64_encode($this->name);
        return array('name', 'age'); // It must return a value of which the elements are the name of the properties returned.
    }
}
$person = new Person('John'); // Initially assigned.
echo serialize($person);
echo '<br/>';

代碼運(yùn)行結(jié)果如下:

It is called when the serialize() method is called outside the class.
O:6:"Person":2:{s:4:"name";s:8:"5bCP5piO";s:3:"age";i:25;}

10. __wakeup()

與 sleep () 方法相比,wakeup () 方法通常用于反序列化操作,例如重建數(shù)據(jù)庫(kù)連接或執(zhí)行其他初始化操作。

 

下面是相關(guān)實(shí)例:

<?php
class Person
{
    public $sex;
    public $name;
    public $age;
    public function __construct($name="",  $age=25, $sex='Male')
    {
        $this->name = $name;
        $this->age  = $age;
        $this->sex  = $sex;
    }
    /**
     * @return array
     */
    public function __sleep() {
        echo "It is called when the serialize() method is called outside the class.<br>";
        $this->name = base64_encode($this->name);
        return array('name', 'age'); // It must return a value of which the elements are the name of the properties returned.
    }
    /**
     * __wakeup
     */
    public function __wakeup() {
        echo "It is called when the unserialize() method is called outside the class.<br>";
        $this->name = 2;
        $this->sex = 'Male';
        // There is no need to return an array here.
    }
}
$person = new Person('John'); // Initially assigned.
var_dump(serialize($person));
var_dump(unserialize(serialize($person)));

代碼運(yùn)行結(jié)果如下:

It is called when the serialize() method is called outside the class.
string(58) "O:6:"Person":2:{s:4:"name";s:8:"5bCP5piO";s:3:"age";i:25;}"
It is called when the unserialize() method is called outside the class.
object(Person)#2 (3) { ["sex"]=> string(3) "Male" ["name"]=> int(2) ["age"]=> int(25) }

11. __toString()

使用 echo 方法直接打印對(duì)象時(shí),將調(diào)用__toString () 方法。

注意:此方法必須返回一個(gè)字符串,否則將在 E_RECOVERABLE_ERROR 級(jí)別上引發(fā)致命錯(cuò)誤。而且您也不能在__toString () 方法中拋出異常。

 

下面是相關(guān)的實(shí)例:

<?php
class Person
{
    public $sex;
    public $name;
    public $age;
    public function __construct($name="",  $age=25, $sex='Male')
    {
        $this->name = $name;
        $this->age  = $age;
        $this->sex  = $sex;
    }
    public function __toString()
    {
        return  'go go go';
    }
}
$person = new Person('John'); // Initially assigned.
echo $person;

運(yùn)行代碼結(jié)果如下:

go go go

那么,如果在類中未定義__toString () 方法怎么辦?讓我們嘗試一下。

 

<?php
class Person
{
    public $sex;
    public $name;
    public $age;
    public function __construct($name="",  $age=25, $sex='Male')
    {
        $this->name = $name;
        $this->age  = $age;
        $this->sex  = $sex;
    }
}
$person = new Person('John'); // Initially assigned.
echo $person;

運(yùn)行代碼結(jié)果如下:

Catchable fatal error: Object of class Person could not be converted to string in D:phpStudyWWWtestindex.php on line 18

顯然,它在頁(yè)面上報(bào)告了一個(gè)致命錯(cuò)誤,PHP 語(yǔ)法不支持這樣的寫法。

 

12. __invoke()

當(dāng)您嘗試以調(diào)用函數(shù)的方式調(diào)用對(duì)象時(shí),__ invoke () 方法將被自動(dòng)調(diào)用。

注意:此功能僅在 PHP 5.3.0 及更高版本中有效。

下面是相關(guān)實(shí)例:

<?php
class Person
{
    public $sex;
    public $name;
    public $age;
    public function __construct($name="",  $age=25, $sex='Male')
    {
        $this->name = $name;
        $this->age  = $age;
        $this->sex  = $sex;
    }
    public function __invoke() {
        echo 'This is an object';
    }
}
$person = new Person('John'); // Initially assigned.
$person();

運(yùn)行代碼結(jié)果如下:

This is an object

如果堅(jiān)持使用對(duì)象作為方法 (但未定義__invoke () 方法),則將得到以下結(jié)果:

 

Fatal error: Function name must be a string in D:phpStudyWWWtestindex.php on line 18

13.__set_state()

從 PHP 5.1.0 開始,在調(diào)用 var_export () 導(dǎo)出類代碼時(shí)會(huì)自動(dòng)調(diào)用__set_state () 方法。

__set_state () 方法的參數(shù)是一個(gè)包含所有屬性值的數(shù)組,其格式為 array ('property'=> value,...)

在以下示例中,我們沒(méi)有定義__set_state () 方法:

<?php
class Person
{
    public $sex;
    public $name;
    public $age;
    public function __construct($name="",  $age=25, $sex='Male')
    {
        $this->name = $name;
        $this->age  = $age;
        $this->sex  = $sex;
    }
}
$person = new Person('John'); // Initially assigned.
var_export($person);

執(zhí)行代碼結(jié)果如下:

Person::__set_state(array( 'sex' => 'Male', 'name' => 'John', 'age' => 25, ))

顯然,對(duì)象的屬性已打印。

 

現(xiàn)在讓我們看看定義__set_state () 方法的另一種情況:

<?php
class Person
{
    public $sex;
    public $name;
    public $age;
    public function __construct($name="",  $age=25, $sex='Male')
    {
        $this->name = $name;
        $this->age  = $age;
        $this->sex  = $sex;
    }
    public static function __set_state($an_array)
    {
        $a = new Person();
        $a->name = $an_array['name'];
        return $a;
    }
}
$person = new Person('John'); // Initially assigned.
$person->name = 'Jams';
var_export($person);

執(zhí)行代碼結(jié)果如下:

 

Person::__set_state(array( 'sex' => 'Male', 'name' => 'Jams', 'age' => 25, ))

14. __clone()

在 PHP 中,我們可以使用 clone 關(guān)鍵字通過(guò)以下語(yǔ)法克隆對(duì)象:

$copy_of_object = clone $object;

但是,使用 clone 關(guān)鍵字只是一個(gè)淺拷貝,因?yàn)樗幸玫膶傩匀詫⒅赶蛟甲兞俊?/p>

如果在對(duì)象中定義了 clone () 方法,則將在復(fù)制生成的對(duì)象中調(diào)用 clone () 方法,該方法可用于修改屬性的值 (如有必要)。

下面是相關(guān)的示例:

<?php
class Person
{
    public $sex;
    public $name;
    public $age;
    public function __construct($name="",  $age=25, $sex='Male')
    {
        $this->name = $name;
        $this->age  = $age;
        $this->sex  = $sex;
    }
    public function __clone()
    {
        echo __METHOD__."your are cloning the object.<br>";
    }
}
$person = new Person('John'); // Initially assigned.
$person2 = clone $person;
var_dump('persion1:');
var_dump($person);
echo '<br>';
var_dump('persion2:');
var_dump($person2);

運(yùn)行代碼結(jié)果如下:

 

Person::__clone your are cloning the object.
string(9) "persion1:" object(Person)#1 (3) { ["sex"]=> string(3) "Male" ["name"]=> string(6) "John" ["age"]=> int(25) }
string(9) "persion2:" object(Person)#2 (3) { ["sex"]=> string(3) "Male" ["name"]=> string(6) "John" ["age"]=> int(25) }

15.__autoload()

__autoload () 方法可以嘗試加載未定義的類。

 

過(guò)去,如果要在程序文件中創(chuàng)建 100 個(gè)對(duì)象,則必須使用 include () 或 require () 來(lái)包含 100 個(gè)類文件,或者必須在同一類文件中定義 100 個(gè)類。 例如以下:

 

/**
 * file non_autoload.php
 */
require_once('project/class/A.php');
require_once('project/class/B.php');
require_once('project/class/C.php');
...if (ConditionA) {
    $a = new A();
    $b = new B();
    $c = new C();
    // …
} else if (ConditionB) {
    $a = newA();
    $b = new B();
    // …
}

那么,如果我們使用__autoload () 方法呢?

 

/**
 * file autoload_demo.php
 */
function  __autoload($className) {
    $filePath = “project/class/{$className}.php”;
    if (is_readable($filePath)) {
        require($filePath);
    }}if (ConditionA) {
    $a = new A();
    $b = new B();
    $c = new C();
    // …
} else if (ConditionB) {
    $a = newA();
    $b = new B();
    // …
}

當(dāng) PHP 引擎第一次使用類 A 時(shí),如果未找到類 A,則 autoload 方法將被自動(dòng)調(diào)用,并且類名稱 “A” 將作為參數(shù)傳遞。因此,我們?cè)?autoload () 方法中需要做的是根據(jù)類名找到相應(yīng)的類文件,然后將其包含在內(nèi)。如果找不到該文件,則 php 引擎將拋出異常。

 

16. __debugInfo()

當(dāng)執(zhí)行 var_dump() 方法時(shí),__debugInfo() 方法會(huì)被自動(dòng)調(diào)用。如果 __debugInfo() 方法未被定義,那么 var_dump 方法或打印出這個(gè)對(duì)象的所有屬性。

 

舉例說(shuō)明:

<?php
class C {
    private $prop;
    public function __construct($val) {
        $this->prop = $val;
    }
    /**
     * @return array
     */
    public function __debugInfo() {
        return [
            'propSquared' => $this->prop ** 2,
        ];
    }
}
var_dump(new C(42));

執(zhí)行結(jié)果:

 

object(C)#1 (1) { ["propSquared"]=> int(1764) }

注意:__debugInfo () 方法應(yīng)該在 PHP 5.6.0 及以上版本中使用。

 

總結(jié)

以上就是我所了解的 PHP 魔術(shù)方法,其中常用的包括 __set() 還有 __get() 和 __autoload()。如果你還有其他疑問(wèn),可以從 PHP 官方網(wǎng)站獲得更多幫助。

分享到:
標(biāo)簽:開發(fā) PHP
用戶無(wú)頭像

網(wǎng)友整理

注冊(cè)時(shí)間:

網(wǎng)站:5 個(gè)   小程序:0 個(gè)  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會(huì)員

趕快注冊(cè)賬號(hào),推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過(guò)答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫(kù),初中,高中,大學(xué)四六

運(yùn)動(dòng)步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動(dòng)步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績(jī)?cè)u(píng)定2018-06-03

通用課目體育訓(xùn)練成績(jī)?cè)u(píng)定