首页 > 代码库 > 魔术方法__clone(), __toString(), __call(), __autoload(), __sleep()和__wakeup()详解

魔术方法__clone(), __toString(), __call(), __autoload(), __sleep()和__wakeup()详解

一、魔术方法__clone()
<?php

class demo{
    public $name;
    public $age;
    
    public function __construct($name,$age){
        $this -> name = $name;
        $this -> age = $age;
    }
    
    public function say(){
        echo "say".$this->name;
    }
    
    //在克隆对象时自动调用
    //作用:可以对新对象的成员属性进行赋值
    public function __clone(){ //克隆时调用这个魔术方法
        $this -> name = "lisi";
        $this -> age = 20;
    }    
}

$demo = new demo("zhangsan",18);
$demo -> say();
echo "<hr>";

$demo1 = clone $demo; //clone克隆一个已经存在的实例化对象

//exit; //退出程序
$demo1 -> say();
?>


二、魔术方法__toString()
<?php

class demo{
    public $name;
    
    public function __construct($name){
        $this -> name = $name;
    }
    
    //__toString() 是直接echo 或 print 对象时自动调用
    //作用:可以直接返回字符串或用于调用流程处理
    public function __toString(){ //输出对象时,也就是echo $demo时,自动调用,必须返回一个字符串值
        $this -> d();
        $this -> e();
        return ‘‘;
    }
    
    private function d(){
        echo "d...";
    }
    
    private function e(){
        echo "e...";
    }
}

$demo = new demo(‘zhangsan‘);
echo $demo;

?>


三、魔术方法__call()
<?php

class db{
    //1.例子1
    //__call() 是在调用一个不存在的方法时自动调用
    //$methodName 不存在的调用方法名
    //$args 所调用的方法里面的参数列表(数组格式)
    /*
    public function __call($methodName,$args){
        echo "你所调用的方法{$methodName}(),参数:";
        print_r($args);
        echo "不存在";
    }
    下面是实例化类
    $db = new db();
    $db -> select(‘a‘,‘b‘,‘c‘); //这个方法是不存在的,当调用不存在的方法时,自动调用__call()
    */
    
    //2.例子2
    
    //SELECT * FROM user WHERE id>2 ORDER DESC LIMIT 0,10
    private $sql = array(
            ‘table‘ => ‘‘,
            ‘field‘ => ‘*‘,
            ‘where‘ => ‘‘,
            ‘order‘ => ‘‘,
            ‘limit‘ => ‘‘
    );
    
    public function __call($methodName,$args){
        
        //判断调用的方法名是否是成员属性数组的下标
        if(array_key_exists($methodName, $this -> sql)){
            $this -> sql[$methodName] = $args[0]; //赋值得到 ‘table‘ => ‘user‘;
        }else{
            die("你所调用的方法{$methodName}()不存在!"); //必须用"", 当用‘‘{$methodName}不显示结果
        }
        
        
        return $this; //返回本对象,为了实现$db->table(‘uesr‘)->filed()的连贯操作
    }
    
    public function select(){
        //判断where赋值了没有
        if($this -> sql[‘where‘]){
            $where = "WHERE {$this -> sql[‘where‘]}";
        }else{
            $where = ‘‘;
        }
        
        if($this -> sql[‘order‘]){
            $order = "ORDER {$this -> sql[‘order‘]}";
        }else{
            $order = ‘‘;
        }
        
        if($this -> sql[‘limit‘]){
            $limit = "LIMIT {$this -> sql[‘limit‘]}";
        }else{
            $limit = ‘‘;
        }
        
        $sql = "SELECT {$this->sql[‘field‘]} FROM {$this->sql[‘table‘]} {$where} {$order} {$limit}";
        echo $sql;
    }
}

$db = new db();
$db -> table(‘user‘) -> field(‘id,username,pwd‘) -> order(‘id DESC‘) -> select(); //调用不存在的table()方法时,触发魔术方法__call()

echo "<pre>";
var_dump($db);
?>


四、魔术方法__autoload()
<?php

//__autoload()实例化不存在的类时,自动调用
//参数:实例化的类名
//作用:让不存在的类包含进来,可以自动引入类文件
function __autoload($className){
    $file = $className.".class.php";
    $path = "./class/".$file;
    
    //判断文件是否存在
    if(file_exists($path)){
        include($path); 
    }else{
        die("你所调用使用的{$className}.class.php 文件不存在");
    }
}

$demo = new demo1(); //demo类在这里不存在
var_dump($demo1);
?>

五、魔术方法__sleep()和__wakeup()
1.串行化代码 serialize.php
<?php
/**
 * serialize() 串行化数组或对象的成员属性(注意:只是串行化对象的成员属性)
 * unserialize() 反串行化
 * $arr = array(‘name‘=>‘zhangsan‘,‘age‘=>18,‘sex‘=>‘nv‘);
 * $str = serialize($arr); //把数组串行化为字符串,串行化时调用__sleep()
 * var_dump($str);

 * $arr1 = unserialize($str); //把字符串转为数组,反串行化时调用__wakeup()
 * var_dump($arr1);
 */

class demo{
    public $name;
    public $age;
    public $sex;
    
    public function __construct($name,$age,$sex){
        $this -> name = $name;
        $this -> age = $age;
        $this -> sex = $sex;
    }
    
    //__sleep(),串行化时自动调用
    public function __sleep(){
        //控制哪些值需要串行化
        return array(‘name‘,‘age‘,‘sex‘);
    }
    
    //__wakeup(),反串行化时自动调用
    public function __wakeup(){
        $this -> age = $this -> age + 1;
    }
}

$demo = new demo(‘zhangsan‘,18,‘nan‘);
$str = serialize($demo);

$handle = fopen(‘./data.txt‘,‘w+‘);
fwrite($handle,$str);
fclose($handle);
var_dump($str);
?>

2.反串行化代码 unserialize.php
<?php 
//include(‘./demo.class.php‘); 如果没有上面的类,就引入类
$str = file_get_contents(‘./data.txt‘);
$d = unserialize($str);
var_dump($d->age);
?>
?>

 

魔术方法__clone(), __toString(), __call(), __autoload(), __sleep()和__wakeup()详解