php7实践指南-ch9类与方法-魔术方法

9.3 魔术方法

9.3.1 __set()和__get()方法

1. __set()方法

__set()方法在代码试图要给未定义的属性赋值时调用,或在类外部修改被private修饰的类属性时被调用。它会传递两个参数:属性名和属性值。

代码示例

<?php
class magic{
    private $_name;
    private $_age='22 years old';
    function __set($key,$value){
        echo 'execute__set method';
        $this->$key=$value;
    }
}

$obj = new magic();
echo $obj->_weight='55kg';//访问类中不存在的$_weight属性被__set()方法拦截
echo $obj->name='chenxiaolong';//在类外部修改private修饰的属性$_name被拦截
echo '</br>';
var_dump($obj);

程序输出

execute__set method55kgexecute__set methodchenxiaolong
object(magic)#1 (4) { ["_name":"magic":private]=> NULL ["_age":"magic":private]=> string(12) "22 years old" ["_weight"]=> string(4) "55kg" ["name"]=> string(12) "chenxiaolong" }

可见程序两次调用了 __set() 方法。

2. __get()方法

当在类外部访问被private或protected修饰的属性或者访问一个类中原来不存在的属性时被调用。使用示例如下:

<?php
class magic1{
    private $__age='22 years old';
    protected $__height='170cm';
    function __get($key){
        echo 'execute __get() method.';
        //var_dump($key);
        $oldKey=$key;
        if(isset($this->$key)){
            return $this->$key;
        }

        $key='_'.$key;
        //var_dump($key);
        if(isset($this->$key)){
            return $this->$key;
        }
        $key='_'.$key;
        var_dump($key);
        if(isset($this->$key)){
            return $this->$key;
        }
        return '$this->'.$oldKey.' not exist';
    }
}

$obj = new magic1();
echo $obj-> age; // 访问被private修饰的属性
echo '</br>';
echo $obj->height;//访问被protected修饰的属性
echo '</br>';
echo $obj->job; //访问不存在的属性


执行以上程序的运行结果为:

execute __get() method.string(5) "__age" 22 years old
execute __get() method.string(8) "__height" 170cm
execute __get() method.string(5) "__job" $this->job not exist

可见“excute __get() method”这个字符串被打印了3次,说明这3次都成功调用了__get()方法。在__get()方法里加入了3个判断,是因为在定义被private和protected修饰的属性时习惯在名称前加上一个或两个下划线,所以在类外部访问一个不存在的属性时可在__get()方法中确定要访问的是否为被加了下划线的非公开属性。

9.3.2 __isset()和__unset()方法

1. __isset()方法

当在类外部对未定义的属性或者非公有属性使用isset()函数时,魔术方法__isset()将会被调用。示例代码如下:

<?php
/*
 * class magic1 演示__isset()方法
 * 当在类外部对未定义的属性或者非公有属性使用isset()函数时,魔术方法__isset()将会被调用。
 * */
class magic2{
    public $father='chenxiaolong';
    private $_name;
    private $_age='22 years old';

    protected $__height='170cm';
    private $_hobby='basketball';
   function __isset($key)
   {
      if(property_exists('magic2',$key)){
          echo 'property'.$key.' exists</br>';
      }else{
          echo 'property'.$key.' not exists</br>';
      }
   }
}

$obj = new magic2();
isset($obj->_hobby); //被private修饰的属性
isset($obj->lover); //不存在的属性
isset($obj->father);//被public修饰的属性,不会触发__set()方法
isset($obj->__height);//被protected修饰的属性


程序输出

property_hobby exists
propertylover not exists
property__height exists

说明:property_exists()用来检测类中是否定义了该属性,用法为property_exists(class_name, property_name),即判断类class_name中是否定义了property_name属性。

 

2. __unset()方法

对类中未定义的属性或非公有属性进行unset()操作时,将会触发__unset()方法。如果属性存在,unset()操作会销毁这个属性,释放该属性在内存中占用的空间。再用对象访问这个属性时,将会返回NULL。

<?php
/*
 * class magic1 演示__unset()方法
 * 对类中未定义的属性或非公有属性进行unset()操作时,将会触发__unset()方法。
 * */
class magic3{
    public $father='chenxiaolong';
    private $_name;
    private $_age='22 years old';

    protected $__height='170cm';
    private $_hobby='basketball';
   function __unset($key)
   {
      if(property_exists('magic3',$key)){
          unset($this->$key);
          echo 'property'.$key.' has been unseted</br>';
      }else{
          echo 'property'.$key.' not exists</br>';
      }
   }
}

$obj = new magic3();
unset($obj->_hobby);
unset($obj->lover);
unset($obj->father);// 存在该属性且被public修饰,不会触发__unset()方法
unset($obj->__height);
?>



程序输出

property_hobby has been unseted
propertylover not exists
property__height has been unseted

9.3.3 __call() 和__ toString() 方法

1. __call() 方法

<?php
/*
 * class magic4 演示__call()方法
 *当试图调用类中不存在的方法时会触发__call()方法。__call()方法有两个参数,即方法名和参数,参数以索引数组的形式存在。
 * */
class magic4{
    function __call($func,$param){
        echo "$func method not exists<br/>";
        var_dump($param);
    }
}
$obj=new magic4();
$obj->register("param1",'param2','param3');


程序输出

register method not exists
array(3) { [0]=> string(6) "param1" [1]=> string(6) "param2" [2]=> string(6) "param3" }

2. __toString()方法

<?php
/*
 * class magic5 演示__toString()()方法
 * 当使用echo或print打印对象时会调用__toString()方法将对象转化为字符串。
 * */
class magic5{
    function __toString(){
     return 'when you want to echo or print the object,__toString() will be called';
    }
}
$obj=new magic5();
print $obj;

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值