<?php
class MagicTest{
public $name;
public static $arr=[];
//__tostring会在把对象转换为string的时候自动调用
public function __tostring(){
return "this is the class MagicTest";
}
//__invoke会在把对象当作一个方法的时候会自动调用
public function __invoke($x){
return "__invoke called with parameter".$x."\n";
}
//方法重载
public function __call($name,$arguments){
echo "Calling ".$name." width parameters: ".implode(',',$arguments)."";
}
//静态方法重载
public static function __callStatic($name,$arguments){
echo "Static calling ".$name." width parameters: ".implode(',',$arguments)."";
}
//-------属性重载------
public function __get($name){
return $name;
}
public function __set($name,$value){
self::$arr[$name]=$value;//如动态设置
}
public function __isset($name){
echo "__isset invoked".$name."\n";
}
public function __unset($name){
echo "unset property".$name."\n";
}
//-------------clone后实例前执行------------------
public function __clone(){
$this->name = "TBD";
}
}
$obj = new MagicTest();
echo $obj.'\n';
$obj(5);
//方法重载
$obj->runTest("para1","para2");//Calling runTest width para...
MagicTest::runTest("para1","para2");//Static calling runTest width ...
//属性重载
echo $obj->className."\n";
$obj->className = "MagicClassX\n";
echo isset($obj->className) .'\n';
echo empty($obj->className) .'\n';
unset($obj->className);
//复制对象实例
$obj2 = clone $obj;//会执行__clone
$obj2 ->name = 'obj2';//只改变了obj2,没有改$obj
?>
__clone方法和clone关键字的使用

<?php
class NbaPlayer{
public $name;
function __clone(){
$this->name='TBD';
}
}
$james=new NbaPlayer();
$james->name='james'."\n";
echo $james->name;
$james2=clone $james;
echo "Before set up jame2s's:".$james2->name."\n";
$james2->name='james2';
echo "james's:".$james->name."\n";
echo "james2's:".$james2->name."\n";
?>
__clone比较常用,用于对一个对象操作,但不想影响原有数据时。
$obj1 = $obj; 不能实现对象的复制,两个对象变量指向同一对象
$obj1 = clone $obj; 可以实现对象的复制,变成值相同的两个对象
使用clone过来的$obj1调用属性时,系统自动调用__clone()方法,在__clone()方法里可以自定义修改克隆的内容,去设置克隆后的对象的初始值。
__clone()方法的使用。在clone一个新对象时 希望和clone过来的数据不一样;可以用__clone()这个函数在下面$this->name = "tbd";在__clone()方法里可以自定义修改克隆的内容,去设置克隆后的对象的初始值。
当希望生成一个新的真正独立存储的对象,但新对象的所有数据和源对象中的相同,这时我们使用关键字 clone来解决;
(前提是在类中定义了 __clone()方法);使用新对象调用属性时,将自动调用__clone()方法(此方法可以对新对象的数据进行修改即初始化)
这就是:想改变一个对象,但是又不想影响源对象,就使用clone;
使用&指向同一个堆栈空间,实际上还是一个对象;直接赋值就变成了两个对象,一个属性值改变时另外属性值也会发生改变,如果用clone进行复制的话,两个对象之间操作不受任何干扰,相互完全独立。

讲师语录:想对一个对象进行操作,但又不想影响源对象的数据,这时使用clone