3、增加__sleep()在序列化时释放掉不在使用的、被遗忘的句柄
<?
class ABaby
{
var $fileName,$fileOpen,$offset,$length;
function ABaby(){
$this->fileName='ABaby.class.php';
$this->fileOpen=fopen($this->fileName,'rb');
$this->offset=0;
$this->length=0;
}
function getData($offset,$length){
$this->offset=$offset;
$this->length=$length;
fseek($this->fileOpen,$offset);
return(fread($this->fileOpen,$length));
}
function getLastData(){
return($this->getData($this->offset,$this->length));
}
function __sleep(){
fclose($this->fileOpen);
}
function __wakeup(){
$this->fileOpen=fopen($this->fileName,'rb');
}
}
$ABaby=new ABaby();
echo($ABaby->getData(7,77));
$ABabyBed=serialize($ABaby);
$newABaby=unserialize($ABabyBed);
echo($newABaby->getLastData());
?>
注释:
运行上面的脚本。出错了:__sleep()应该返回一个数组,这个属组包含类中的实例变量的名字。这是__sleep()的精致之处:可以告诉解析器哪些变量需要被序列化保存下来。这个属组不包含的实例变量(注意这个数组存放的实际是变量名而非值)将被抛弃,这样可以给序列化产生的字串瘦身、并在反序列化时提速。现在看来,__sleep()可以从两个方面优化系统性能:
1、释放资源;
2、有选择性的序列化实例变量。
修正上面的代码如下:4、修正了__sleep()定义
<?
class ABaby
{
var $fileName,$fileOpen,$offset,$length;
function ABaby(){
$this->fileName='ABaby.class.php';
$this->fileOpen=fopen($this->fileName,'rb');
$this->offset=0;
$this->length=0;
}
function getData($offset,$length){
$this->offset=$offset;
$this->length=$length;
fseek($this->fileOpen,$offset);
return(fread($this->fileOpen,$length));
}
function getLastData(){
return($this->getData($this->offset,$this->length));
}
function __sleep(){
fclose($this->fileOpen);
$arr=array();
array_push($arr,'fileName');
array_push($arr,'offset');
array_push($arr,'length');
return($arr);
}
function __wakeup(){
$this->fileOpen=fopen($this->fileName,'rb');
}
}
$ABaby=new ABaby();
echo($ABaby->getData(7,77));
$ABabyBed=serialize($ABaby);
$newABaby=unserialize($ABabyBed);
echo($newABaby->getLastData());
?>
注释:
运行正常,结果符合预期。 最后补充一点有关对象序列化的内容。对象序列化通常被用来保存对象当时的状态以备后用,更适合于跨页、跨时间、跨服务器交换/传递对象格式的数据。
对于跨页传递对象,可能会有人提出直接使用session存放对象,这未尝不可。不过有两个问题值得注意:
1、事实上变量被存放进session时会被自动序列化成字符串再存入;从session中读取对象时,解析器会首先反序列化(unserialize())再返回对象。自然,魔法函数对这个过程也应该是有效的。
2、由于session是会话级变量,所有使用session_start的页面都必须包含类定义的脚本文件,因为在session_start时会自动发序列化(unserialize())存放的对象(前面自动序列化得到的字符串)
这样看来,向session中存放对象要付出一定的代价。所以个人建议是将要保存的对象序列化得到的字符串保存进session,使用时再显式的反序列化出实例对象。 关于魔法函数的说告一段落。
至此,本人在Php对象编程中遇到的几个典型的兼容性问题以及部分新的基本介绍完毕。水平所限,有所疏漏或谬误请予指正。
多谢各位的阅读!
举个简单的事实,我们经常使用的数组,它有一些固定的方法,比如count、arry_push等等。虽然在Php中数组array并没有以数组的姿态出现,但是类的机理和它似曾相识。可以把一些经常用到的方法、属性绑在一起成为类(抽象描述),当需要的时候通过一些参数定制出一个具体的对象(实例化)。
可以看一下我的前面的系列贴子中有一小段相关回复。