php中的魔术方法

魔术方法是不需要调用,在某些情况下 系统自动调用的方法。此类方法的特征是方法名都以双下划线__开头

1 构造方法__construct()

构造方法是当对象被实例化时自动调用的方法,该方法是被刚实例化的对象调用。现比如定义学生类(Stu),在类中声明__construct()方法
class Stu{
	public $stu_name;
	private $stu_age;
	public static $count=0;
	
	
	public  function __construct($name,$age){
		$this->stu_name=$name;
		$this->stu_age=$age;
		self::$count++;
	}

现实例化对象,并输出该对象

$stu1=new Stu("charlene",18);
var_dump($stu1);//输出内容  object(Stu)[1]   public 'stu_name' => string 'charlene' (length=8)   private 'stu_age' => int 18

2 克隆方法__clone()

当利用clone关键字复制对象时 相当于增加了一个实例 本例中Stu类中的$count变量是统计学生的人数,但是如果使用克隆方法 相当于将源对象的所有信息都复制 count变量没哟相应的增加一  
<pre name="code" class="php">$stu2=new Stu("cheng",20);
echo Stu::$count;//输出2
$stu3=clone $stu2;
echo Stu::$count;//输出2
 

__clone()方法是在克隆时自动执行的方法,在Stu类中添加该方法
public function __clone(){
		self::$count++;
}

然后再调用
$stu3=clone $stu2;<pre name="code" class="php">echo Stu::$count;//输出3
 

3 析构方法__destruct()

当释放资源时 会调用析构方法
这里需要注意一下  php内所有的资源(变量)都是脚本级别的,当脚本运行结束时会自动消失(释放内存)所以当脚本结束时 会自动调用析构函数
 但是为了节约内存,也应该在某个数据使用完成时,手动释放资源(释放变量 通过unset 变量,释放对象通过析构函数)
什么样的对象会消失
1 unset了当前的对象的变量
2 当脚本执行结束时 所有的资源都会消失
3 如果引用该对象的变量 引用了其他的数据,导致原来对象数组的消失
当上述三种情况有一种成立时  会自动调用析构函数

在类Stu中写入析构函数
public function __destruct(){
		echo "destruct run...";
}
当不释放资源 脚本运行结束时 网页中也会输出“destruct run..."

4 __sleep()方法

4.1 序列化与反序列化

当将数据保存到文件中时,字符串数据(字节流和二进制流)类型能够正常保存 但当保存其他数据类型时, 其他类型的数据类型时不能保存的。如
$str="abcd";
file_put_contents('data.txt',$str);
$get_str=file_get_contents('data.txt');
var_dump($get_str);//输出 <small style="font-family: Arial, Helvetica, sans-serif;">string</small><span style="font-family: Arial, Helvetica, sans-serif;"> </span><span style="font-family: Arial, Helvetica, sans-serif; color: rgb(204, 0, 0);">'abcd'</span><span style="font-family: Arial, Helvetica, sans-serif;"> </span><span style="font-family: Arial, Helvetica, sans-serif; "><em>(length=4)</em></span>
$data= array('a','b','c','d');
file_put_contents('data.txt',$data);
//传入的是数组类型的数据 读取出的是字符串类型的数据
$get_arr=file_get_contents('data.txt');
var_dump($get_arr);//输出string 'abcd'(length=4)

为了读取数据内容与写入的数据类型一致,在保存数据之前需获得当前保存数据的格式,需要用到序列化操作
序列化操作:将数据的数据类型、数据结构记录下来 保存到一个字符串中,序列化利用serialize()函数来完成

$s_data=array('apple'=>'苹果','banana'=>'香蕉');
var_dump($ser_data=serialize($s_data));
//结果 string 'a:2:{s:5:"apple";s:6:"苹果";s:6:"banana";s:6:"香蕉";}' (length=57)
var_dump(file_put_contents('data.txt',$ser_data));//

在得到一个序列化字符串后 需要进行反序列化才能得到原来的数据,利用unserialize()完成
var_dump(unserialize(file_get_contents('data.txt')));
其输出结果和传入的数组是一样的

在序列化和反序列化时  需要注意:对象如果能够工作,不单需要对象自己所保存的数据,也需要对象所属类,所维护的类结构。因此,在反序列化时,仅有对象数据
不能得到完整的对象,需要同时引用类的定义才可以,否则 得到的对象 就变成了php内置类__PHP_Incomplete_Class的对象
例如 当在mysqlModel.php中定义了一个mysqlModel类 当对mysqlModel类实例化的对象序列化并写入data.txt文件后
$model=new mysqlModel(array());
$s_model=serialize($model);
var_dump(file_put_contents('data.txt', $s_model));
当在文件magic.php中读取并反序列化后 并输出
$get_model=file_get_contents('data.txt');
var_dump(unserialize($get_model));
输出结果


当在文件magic.php引入mysqlModel类时
include 'mysqlModel.php';
$get_model=file_get_contents('data.txt');
var_dump(unserialize($get_model));
输出结果

4.2 __sleep()
序列化反序列化可以用于所有的数据类型,但是资源类型 即使被序列化了,也不能保存,因为一个脚本维护的资源 在脚本结束时,会自动释放。因此,如果一个对象的某些属性是资源型,是不需要保存的(保存了也没有意义)。如果需要控制 在序列化对象时 哪些数据应该保存 哪些数据不用保存 可以使用序列化的魔术方法完成。
__sleep() 该方法会返回一个数组 数组内的每一个元素 是一个当前对象的属性名。凡是出现在数组内的元素 所代表的属性都会被保存
例如 在mysqlModel类中,因为含有资源类型数据$_link,为了节约内存 当序列化时,不序列化$_link变量
public function __sleep(){
	return array('_host','_port','_user','_pass','_dbname','_charset');
}

5 __wakeup()方法

与__sleep()相对 会在反序列化对象时 存在一个用户初始化被反序列化的对象的某些属性的功能(eg 应该在反序列化时,将数据库再次连接上。与之相对的就是 _wakeup(),该函数是 反序列化时执行的魔术方法,负责对不能被序列化保存的数据重新初始化
如在反序列化时重新获得$_link的值
public function __wakeup(){
	//调用连接数据库的方法
	$this->_connect();
	//设置字符集
	$this->_setCharset();
	//选择数据库
	$this->_selectDB();

}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值