您的位置:首页 > 编程语言 > PHP开发

php之魔术方法

2015-05-29 20:20 666 查看
  指某些情况下,会自动调用的方法,称为魔术方法
  php面向对象中,提供了这几个魔术方法,他们的特点都是以双划线__开头的,比如
  __construct(),__destruct(),__call(),__callStatic(),__get(),__set(),__isset(),__unset(),__sleep(),__wakeup(),__toString(),__invoke(),__set_state(),__clone()等

<?php
/****
魔术方法:
指某些情况下,会自动调用的方法,称为魔术方法
php面向对象中,提供了这几个魔术方法
他们的特点都是以双划线__开头的
__construct(),__destruct(),__call(),__callStatic(),__get(),__set(),__isset(),__unset(),__sleep(),__wakeup(),__toString(),__invoke(),__set_state(),__clone
****/
/***
class Human{
public $age = 29;
public function __clone(){
echo '有人克隆我';
}
}
$lisi = new Human();
$zhangsan = clone $lisi;
print_r($zhangsan);
***/

/***
class Human{
private $money = '2333';
protected $age = 22;
public $name = 'lily';
}
$lily = new Human();
echo $lily->name;//lily
//echo $lily->age;//权限报错
//echo $lily->sister;//unfined property
***/

class Human{
private $money = '2333';
protected $age = 22;
public $name = 'lily';
public function __get($p){
echo '你想访问我的',$p,'属性<br />';
}
}
$lily = new Human();
echo $lily->name,'<br />';
echo $lily->age;//你想访问我的age属性
echo $lily->money;//你想访问我的money属性
echo $lily->friend;//你想访问我的friend属性
/***
总结:
当我们调用一个权限上不允许的属性或不存在的属性时,__get()就会自动运行
并且会自动传一个参数,参数值是属性名(),而不是属性值,注意参数只能传一个,而且必须要写上

流程:
$lily->age---无权-->__get(age);
$lily->friend---没有此属性-->__get(friend);
相当于给人提供了一个接口,我们能自定义用户访问时的处理方法
***/
echo $lily->aaa = 111;
echo $lily->bbb = 222;
print_r($lily);
/***
其实,对象就是一个属性集,在js中更明显,
如果这么随便就能添加属性,导致这个对象属性过多,不好管理
***/
class Stu{
private $money = 2333;
protected $age = 23;
public $name = 'hmm';
public function __set($a,$b){
echo '你想设置我的',$a,'属性<br />';
echo '且值是',$b,'<br />';
}
}
echo '<hr />';
$hmm = new Stu();
$hmm->aaa = 111;
$hmm->money = 55;
$hmm->age = 34;
print_r($hmm);

echo '<br />';
$hmm->name = 'lily';
print_r($hmm);

/***
总结:
当为无权操作或不存在的属性赋值时,__set()自动调用
且自动传2个参数,分别是属性名,属性值
比如
$hmm->age = 30 ---无权--->__set(age,30);
***/

echo '<hr />';
class Dog{
protected $bone = '猪腿骨';
public $leg = 4;
public function __unset($p){
echo '你想去掉我的',$p,'<br />';
}
public function __isset($p){
echo '你想判断我的',$p,'属性存不存在<br />';
return 1;
}
}
$hua = new Dog();
if (isset($hua->leg)) {
echo $hua->leg,'<br />';
}
if (isset($hua->tail)) {
echo '有tail属性';
}else {
echo '没有tail属性';
}
/***
__isset()方法,
当isset()判断对象不可见的属性(private/protected/)或不存在的属性,__isset()会自动运行

问:isset($obj->xyz)属性,为真,能说明类声明了一个xyz属性吗?
答:不能

***/
echo '<hr />';
echo 'unset测试';
print_r($hua);
unset($hua->leg);
print_r($hua);

unset($hua->tail);
unset($hua->bone);

/***
总结:
当用unset销毁对象的不可见属性/不存在属性时,__unset()自动运行
unset($hua->tail)--不存在tail属性-->__unset(tail)
***/

/***
__call
当调用一个不可访问的方法(未定义的,或不可见的)时,__call自动运行
__callStatic
当调用一个不可访问的静态方法(未定义的,或不可见的),__callStatic自动运行
***/
class Human {
public function hello(){
echo 'hello <br />';
}

private function t(){

}
static public function __callStatic($method,$arguments){
echo '你想调用一个无权调用或不存在的静态方法',$method,'<br />';
echo '调用时还传来了参数<br />';
print_r($arguments);
echo '<br />';

}
public function __call($method,$arguments){

echo '你想调用一个不存在的方法',$method,'<br />';
echo '调用时还传来了参数<br />';
print_r($arguments);
echo '<br />';
}

}

$lisi = new Human();
$lisi->hello();
$lisi->say(1,2,3);//调用一个未定义的方法Fatal error: Call to undefined method Human::say()
$lisi->t('a','b','c');
/*
$lisi->say(1,2,3);---没有say()方法--->__call('say',array(1,2,3))运行
*/
Human::cry('痛苦','嚎哭','鬼哭');

/***
Human::cry(1,2,3);---没有cry()静态方法--->__callStatic('cry',array(1,2,3))运行
***/
/*
为什么__callStatic()这个魔术方法和其他的魔术方法的颜色不一样?

答:这个方法是PHP5.3里才添加的,比较新
可能老版本的编辑器的语法文件里还没有
*/

?>


  

  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: