首页 > 编程笔记 > PHP笔记 阅读:26

PHP魔术方法大汇总(附带实例)

PHP 中提供了内置的拦截器,也称为魔术方法,它可以“拦截”发送到未定义方法和属性的消息。魔术方法通常以两个下划线__开始。

__set() 方法

__set() 方法在代码试图要给未定义的属性赋值时调用,或在类外部修改被 private 修饰的类属性时被调用。它会传递两个参数:属性名和属性值。通过 __set() 方法也可实现对 private 关键词修饰的属性值进行更改。

__set() 方法使用的示例如下:
<?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 "<br />";
$obj->_name = 'chenxiaolong';  //在类外部修改private修饰的属性$_name被拦截
?>
执行以上程序的输出结果为:

execute __set method 55kg
execute __set method

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

__get() 方法

当在类外部访问被 private 或 protected 修饰的属性或者访问一个类中原来不存在的属性时被调用。使用示例如下:
<?php
class magic{
    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;
        if(isset($this->$key)){
            return $this->$key;
        }
        $key = '_' . $key;
        if(isset($this->$key)){
            return $this->$key;
        }
        return '$this->' . $oldKey . ' not exist ';
    }
}
$obj = new magic();
echo $obj->_age;  //访问被 private 修饰的属性
echo "<br />";
echo $obj->__height;  //访问被 protected 修饰的属性
echo "<br />";
echo $obj->job;  //访问不存在的属性
?>
执行以上程序的运行结果为:

execute __get() method 22 years old
execute __get() method 170cm
execute __get() method $this->job not exist

可见“excute__get()method”这个字符串被打印了 3 次,说明这 3 次都成功调用了 __get() 方法。

在 __get() 方法里加入了 3 个判断,是因为在定义被 private 和 protected 修饰的属性时习惯在名称前加上一个或两个下划线,所以在类外部访问一个不存在的属性时可在 __get() 方法中确定要访问的是否为被加了下划线的非公开属性。

__isset() 方法

当在类外部对未定义的属性或者非公有属性使用 isset() 函数时,魔术方法 __isset() 将会被调用。示例代码如下:
<?php
class magic{
    public $father = 'chenxiaolong';
    private $_name;
    //private $_wight = '55kg';
    private $_age = '22 years old ';
    protected $__height = '170cm ';
    private $_hobby = 'basketball';
    function __isset($key){
        if (property_exists('magic', $key)) {
            echo 'property ' . $key . ' exists<br/>';
        } else {
            echo  'property ' . $key . ' not exists<br/>';
        }
    }
}
$obj = new magic();
isset($obj->_hobby);  //被private修饰的属性
isset($obj->lover);  //不存在的属性
isset($obj->father);  //被 public 修饰的属性, 不会触发 __isset() 方法
isset($obj->__height);  //被 protected 修饰的属性
?>
执行以上程序打印的结果为:

property _hobby exists
property lover not exists
property __height exists

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

__unset() 方法

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

示例如下:
<?php
class magic{
    public $father = 'chenxiaolong';
    private $_name;
    //private $_wight = '55kg';
    private $_age = '22 years old ';
    protected $__height = '170cm ';
    rivate $_hobby = 'basketball';
    function __unset($key){
        if (property_exists('magic', $key)) {
            unset($this->$key);
         echo 'property' . $key . ' has been unseted<br/>';
        } else {
         echo  'property ' . $key . ' not exists<br/>';
        }
    }
}
$obj = new magic();
unset($obj->_hobby);
unset($obj->lover);
unset($obj->father);  // 存在该属性且被 public 修饰, 不会触发 __unset() 修饰
unset($obj->__height);
?>
执行以上程序的打印结果为:

property_hobby has been unseted
property lover not exists
property__height has been unseted

__call() 方法

当试图调用类中不存在的方法时会触发 __call() 方法。__call() 方法有两个参数,即方法名和参数,参数以索引数组的形式存在。

使用示例如下:
<?php
class magic{
    function __call($func,$param){
        echo "$func method not exists <br/>";
        var_dump($param);
    }
}
$obj = new magic();
$obj->register('param1','param2','param3');
?>
以上代码的输出结果为:

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

__toString() 方法

当使用 echo 或 print 打印对象时会调用 __toString() 方法将对象转化为字符串。

使用示例如下:
<?php
class magic{
    function __toString(){
        return 'when you want to echo or print the object, __toString() will be called';
    }
}
$obj = new magic();
print $obj;
?>
执行以上程序输出的结果为:

when you want to echo or print the object, __toString() will be called

编程帮,一个分享编程知识的公众号。跟着站长一起学习,每天都有进步。

通俗易懂,深入浅出,一篇文章只讲一个知识点。

文章不深奥,不需要钻研,在公交、在地铁、在厕所都可以阅读,随时随地涨姿势。

文章不涉及代码,不烧脑细胞,人人都可以学习。

当你决定关注「编程帮」,你已然超越了90%的程序员!

编程帮二维码
微信扫描二维码关注

所有教程

优秀文章