首頁  >  文章  >  後端開發  >  php中的魔術方法

php中的魔術方法

WBOY
WBOY原創
2016-08-08 09:30:101040瀏覽

PHP魔術方法:

__construct(), __destruct(), __call(), __callStatic(), __get(), __set(), __isset(), __unset(), __sleep( __toString(),__invoke(),__set_state(), __clone() 和__debugInfo() 等方法在PHP 中稱為"魔術方法"(Magic methods)。在命名自己的類別方法時不能使用這些方法名,除非是想使用其魔術功能。

__construct(),类的构造函数
__destruct(),类的析构函数
__call(),在对象中调用一个不可访问方法(私有或者不存在)时调用
__callStatic(),用静态方式中调用一个不可访问方法时调用
__get(),获得一个类的成员变量时调用
__set(),设置一个类的成员变量时调用
__isset(),当对不可访问属性调用isset()或empty()时调用
__unset(),当对不可访问属性调用unset()时被调用。
__sleep(),执行serialize()时,先会调用这个函数
__wakeup(),执行unserialize()时,先会调用这个函数
__toString(),类被当成字符串时的回应方法
__invoke(),调用函数的方式调用一个对象时的回应方法
__set_state(),调用var_export()导出类时,此静态方法会被调用。
__clone(),当对象复制完成时调用

__construct()和__destruct()
構造函數__construct()在物件被創建的時候調用,析構函數__destruct()在物件消亡的時候被調用

<?php &#160;
class ConDes
{
&#160;&#160;&#160; protected $a = &#39;&#39;;

&#160;&#160;&#160; function __construct(){
&#160;&#160;&#160;&#160;&#160;&#160;&#160; echo &#39;在构造函数中<br>';
    }

    function __destruct(){

        echo '在析构函数中<br>';
    }
}

$val = new ConDes();
unset($val);

?><pre name="code" class="php">
輸出:

在建構函式中在析構函式中

__call()和__callStatic()在物件中呼叫一個不可存取方法時會呼叫這兩個方法,後者為靜態方法。

<?php  
class MethodTest  
{
    public function __call ($name, $arguments) {
    var_dump($arguments);
        echo "object method $name and ".implode(',',$arguments)."<br>";
    }

    public static function __callStatic ($name, $arguments) {
        echo "static method $name and ".implode(',',$arguments)."<br>";
    }
}

$obj = new MethodTest;
$obj->runTest('in object context','another arg');
MethodTest::runTest('in static context');  
?>
輸出:

array (size=2)
  0 => string 'in object context' (length=17)
  1 => string 'another arg' (length=11)
object method runTrunT 和 in object context, runTest and in static context

__get(),__set(),__isset()和__unset()

當取得一個不可存取的類別成員變數或設定一個不可存取的類別成員變數時呼叫這兩個函數。

<?php
class MethodTest  
{
    private $data = array();
    private $a = &#39;&#39;;
    public $bbb = &#39;&#39;;

    public function __set($name, $value){
        $this->data[$name] = $value;
		echo '__set';
		var_dump($this->data);
    }

    public function __get($name){
		echo '__get';
		var_dump($this->data);
        if(array_key_exists($name, $this->data))
            return $this->data[$name];
        return NULL;
    }

    public function __isset($name){
		echo '__isset';
        return isset($this->data[$name]);
    }

    public function __unset($name){
		echo '__unset';
        unset($this->data[$name]);
    }
}

$in = new MethodTest();
$in->a = 'aaaa';
$aaa = $in->a;
$res = isset($in->c)? 'set':'not set';
echo '<br>'.$res.'<br>';
unset($in->a);
?>
輸出: __set

array (size=1)
  'a' => string 'aaaa' (length=4)
__get
array (size=1)
  'a' => string '' (length=4)__isset
not set
__unset

__sleep()和__wakeup()

當我們在執行serialize()和unserialize()時,會先呼叫這兩個函數。例如我們在序列化一個物件時,這個物件有一個資料庫鏈接,想要在反序列化中恢​​復連結狀態,則可以透過重構這兩個函數來實現連結的恢復。


<span></span><pre name="code">&lt;?php class Connection { &amp;#160;&amp;#160;&amp;#160; public $link; &amp;#160;&amp;#160;&amp;#160; private $server, $username, $password, $db; &amp;#160;&amp;#160; &amp;#160; &amp;#160;&amp;#160;&amp;#160; public function __construct($server, $username, $password, $db) &amp;#160;&amp;#160;&amp;#160; { &amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; $this-&gt;server = $server;         $this-&gt;username = $username;         $this-&gt;password = $password;         $this-&gt;db = $db;         $this-&gt;connect();     }          private function connect()     {         $this-&gt;link = mysql_connect($this-&gt;server, $this-&gt;username, $this-&gt;password);         mysql_select_db($this-&gt;db, $this-&gt;link);     }          public function __sleep()     {     echo 'sleep&lt;br&gt;';         return array('server', 'username', 'password', 'db');     }          public function __wakeup()     {     echo 'wakeup&lt;br&gt;';         $this-&gt;connect();     } } $a = new Connection('localhost','mosi','moshi','test'); $sql = 'select id,username from user limit 1'; $res = mysql_query($sql,$a-&gt;link); $res = mysql_fetch_array($res); var_dump($res); $sres = serialize($a); mysql_close($a-&gt;link); //unset($a); $unsres = unserialize($sres); var_dump($unsres); $sql = 'select id,username from user limit 1'; $ress = mysql_query($sql,$unsres-&gt;link); $ress = mysql_fetch_array($ress); var_dump($ress); ?&gt;</pre>輸出:

array (size=4)  0 => string '1' (length=1)<span>  'id' => string '1' (length=1)<br>  1 => string 'm0sh1' (length=1)<br>  1 => string 'm0sh1' <br>  'username' => string 'm0sh1' (length=5)<br>sleep<br>wakeup<br>object(Connection)[2]<br>  public 'link' => resource(6, mysql link)<br>  private 'link' => resource(6, mysql link)<br>  private 'link' => resource(6, mysql link)<br>  private 'link' => resource(6, mysql link)<br>  private 'link' => resource(6, mysql link)<br>  private 'link' => resource(6, mysql link)<br>  private 'link' => resource(6, mysql link)<br> localhost' (length=9)<br>  private 'username' => string 'moshi' (length=4)<br>  private 'password' => string 'moshi' (length=5)<br>  private 'db' => string 'test. (length=4)</span>array (size=4)  0 => string '1' (length=1)

  'id' => string '1' (length=1)

  1 => string 'm0sh1' (length  1 => string 'm0sh1' (length =5)  'username' => string 'm0sh1' (length=5)

<span><br></span>

__toString()<span></span>

__toString()

物件當成字串時的回應方法。例如使用echo $obj;<span></span><span></span>

<?php  
class TestClass  
{
    public function __toString() {
        return &#39;this is a object&#39;;
    }
}

$class = new TestClass();
echo $class;  
?>
輸出:





this is a object

這個方法只能回傳字串,而且不可以在這個方法中拋出異常,否則會出現致命錯誤。



__invoke()

呼叫函數的方式呼叫一個物件時的回應方法。

<?php
class Invoke{
	public function __invoke(){
		echo 'in invoke<br>';
	}
}

class noInvoke{

}

$obj = new Invoke();
$obj();

var_dump(is_callable($obj));

$obj2 = new noInvoke();
//$obj2();
var_dump(is_callable($obj2));
輸出:

in invoke
boolean true
boolean false

__set_state()
呼叫var_export()導出類別時,此靜態方法會被呼叫。

<?php  
class A  
{
    public $var1;
    public $var2;
	public static function __set_state ($arr) {
        $obj = new A;
        $obj->var1 = 'var11';
        $obj->var2 = $arr['var2'];
        return $obj;
    }
}

$a = new A;
$a->var1 = 5;
$a->var2 = 'foo';
var_dump($a);  
var_export($a);  

eval('$ress = '.var_export($a,true).';');
var_dump($ress);

?>

輸出:

object(A)[1]
  public 'var1' => int 5

  public 'var2' => string 'foo' (length=3)
  public 'var2' => string 'foo' (length=3)

Aarray( ' => 5, 'var2' => 'foo', ))

object(A)[2]
  public 'var1' => string 'var11' (length=5)
  public 'var2' => string 'foo ' (length=3)

__clone()

當物件複製完成時呼叫。

<?php  
class Singleton {  
    private static $_instance = NULL;

    // 私有构造方法 
    private function __construct() {}

    public static function getInstance() {
        if (is_null(self::$_instance)) {
            self::$_instance = new Singleton();
        }
        return self::$_instance;
    }

    // 防止克隆实例
    public function __clone(){
        die('Clone is not allowed error: ' . E_USER_ERROR);
    }
}


$a = Singleton::getInstance();
$b = Singleton::getInstance();

if( $a === $b ){
	echo 'equal<br>';
}

$c = clone $b;
?>
輸出: 🎜equal🎜Clone is not allowed error: 256🎜🎜🎜PHP 魔術常數:簡介在這裡🎜🎜 🎜 以上就介紹了 php中的魔術方法,包括了方面的內容,希望對PHP教程有興趣的朋友有幫助。 🎜 🎜 🎜
陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn