• 技术文章 >php教程 >php手册

    php 魔术函数使用说明

    2016-06-13 12:18:55原创570
    什么是魔术函数?
    对于__开头的函数就命名为魔术函数, 此类函数都在特定的条件下触发的.比如: __set() __get()等
    在设置或取不存在的属性时候触发.
    有那些魔术函数呢?
    总的来说, 有下面几个魔术函数
    __construct() __destruct() __get() __set() __isset() __unset() __call() __callStatic()
    __sleep() __wakeup() __toString() __set_state() __clone() __autoload()
    __construct()当实例化一个对象的时候,这个对象的这个方法首先被调用。
    __destruct()当删除一个对象或对象操作终止的时候,调用该方法。

    复制代码 代码如下:


    class test1 {
    public function __construct() {
    var_dump(__function__);
    }
    public function __destruct() {
    var_dump(__function__);
    }
    }
    $t1 = new test1 ;
    unset($t1);


    __get当试图读取一个并不存在的属性的时候被调用。
    __set当试图向一个并不存在的属性写入值的时候被调用。
    __isset当试图检测一个并不存在的属性时候被调用。
    __unset当试图取消一个并不存在的属性时候被调用。

    复制代码 代码如下:


    class test2 {
    public $name3;
    public function __set($key, $value) {
    var_dump(__function__. '
    KEY:'
    .$key.'
    Value:'
    .$value);
    }
    public function __get($key) {
    var_dump(__function__. 'KEY:'.$key);
    }
    public function __isset($key) {
    var_dump(__function__. ' KEY:'.$key);
    }
    public function __unset($key) {
    var_dump(__function__. ' KEY:'.$key);
    }
    }
    $t =new test2 ;
    $t->name = "steven";
    $t->name2;
    $t->name3;
    isset($t->name2);
    isset($t->name3);
    unset($t->name4);


    __sleep当进行序列化对象时候调用
    __wakeup当进行反序列对象时候调用
    需要注意一点:
    1. __sleep()必须返回一个数组或者对象(一般返回的是$this),返回的值将会被用来做为序列化的
    值。
    如果不返回这个值,则序列化失败。这也意味着反序列化将不会触发__wakeup事件。
    2. 序列化会保存默认赋值的属性.如果要通过实例化赋值的内容,则需要属性在__sleep()返回数组的
    指定.
    如$id与$id2的区别.

    复制代码 代码如下:


    class test3 {
    public $name = "steven";
    public $id = "1"; public $id2;
    public function __sleep() {
    var_dump(__function__); // 序列化不成功.没有返回值.反序列也失败 //
    return array("name"); // 序列化成功.有返回值.反序列成功.id2属性能被恢复 //
    return array("name", "id2");// 序列化成功.有返回值.反序列成功.id2属性不能被恢复
    return array("name"); }
    public function testEcho() {
    var_dump($this->name);
    var_dump($this->id);
    var_dump($this->id2);
    }
    public function __wakeup() {
    var_dump(__function__);
    $this->testEcho();
    }
    }
    $t3= new test3 ;
    $t3->id2 = uniqid();
    $t3s = serialize($t3);
    unserialize($t3s);


    __toString当直接打印一个对象的时候,这个方法将会被调用

    复制代码 代码如下:


    class test4 {
    public function __toString() {
    return "toString";
    }
    }
    $t4 = new test4();
    echo $t4;
    print $t4;
    var_dump($t4);
    print_r($t4);


    __call($func, $param) 当尝试调用一个不存在的方法的时候被调用.
    这个方法必须有两个参数,第一个为调用的方法名,第二个是一个被调用方法的参数数组。
    需要注意的是,当你在一个子类调用父类的private的方法,或者在实例里调用类的非protect方法的
    时候,并不会调用__call()

    复制代码 代码如下:


    class test5 {
    public function __call($func, $param) {
    var_dump('Function:'.$func);
    var_dump($param);
    }
    }
    $t5 = new test5;
    $t5->echoTest('xx','xx','xx');


    __callStatic()当尝试调用一个不存在的静态方法的时候被调用
    这个方法必须有两个参数,第一个为调用的方法名,第二个是一个被调用方法的参数数组。
    在PHP5.3中出现

    复制代码 代码如下:


    class test51 {
    public function __callStatic($fun, $param) {
    var_dump('Function:'.$func);
    var_dump($param);
    }
    }
    test51::test('xx','xx','xx');


    __set_state()当用var_export导出实例的时候被调用.此方法有一个参数,为包含所导出的实例的所
    有成员属性的一个数组

    复制代码 代码如下:


    class test6 {
    public function __set_state($arr){
    var_dump($arr);
    }
    }
    $t6 = new test6;
    $t6->age = "12";
    var_export($t6, true);
    var_export($t6);
    eval('
    $b='
    .var_export($t6,true).';');
    print_r($b);


    __clone()当克隆实例时候被调用.
    注意:
    1.在php5里,对象间的赋值总是以地址引用来传递的.
    2.如果要以实际值来传递,则需要用到clone关键词
    3.clone的只是实例。如果实例中的某个成员属性也是个实例,那么这个成员属性还是会以引用方法被
    传递到新的实例。
    // 对象间的赋值总是以地址引用来传递的. $t71 $t72的age属性是一样的.

    复制代码 代码如下:


    class test71 {
    public $age = 10;
    }
    $t71 = new test71();
    $t72 = $t71 ;
    var_dump($t71->age) ;
    $t71->age =12 ;
    var_dump($t71->age) ;
    var_dump($t72->age) ; // 如果要以实际值来传递,则需要用到clone关键词 $t73 = clone $t71; $t71->age = 13 ; var_dump($t71->age) ;
    var_dump($t73->age) ; // 如果实例中的某个成员属性也是个实例,那么这个成员属性还是会以引用方法被传递到新的实例。


    复制代码 代码如下:


    class test74 {
    public $age = 10;
    public $sub = null;
    }
    class test75 {
    public $age = 11;
    }
    $i = new test74;
    $i->sub = new test75();
    $i1 =clone $i;
    var_dump($i1->sub->age);
    $i->sub->age = 12;
    var_dump($i1->sub->age);


    // $i 和$i1虽然不是指向同一个实例,但是它们的成员属性$sub却是指向同一个实例。这时候,我们必须借
    助__clone这个方法来对$sub进行复制。 // $i2和$3指向不同实例.成员属性$sub也指向不同实例.

    复制代码 代码如下:


    class test76 {
    public $age = 10;
    public $sub = null;
    public function __clone() {
    $this->sub = clone $this->sub;
    }
    }
    $i2 = new test76();
    $i2->sub = new test75();
    $i3 = clone $i2;
    $i2->sub->age = 15 ;
    var_dump($i3->sub->age);


    __autoload()函数.当创建一个实例化的时候,如果对应的类不存在,则会被调用

    复制代码 代码如下:


    function __autoload($class) {
       if ( $class == "test8" ){
    require_once dirname(__FILE__).'/class8.php';
    }
    }
    spl_autoload();
    $t8 = new test8;
    var_dump($t8->age);

    php入门到就业线上直播课:查看学习

    声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn核实处理。

    前端(VUE)零基础到就业课程:点击学习

    清晰的学习路线+老师随时辅导答疑

    自己动手写 PHP MVC 框架:点击学习

    快速了解MVC架构、了解框架底层运行原理

    上一篇:php microtime获取浮点的时间戳 下一篇:自己动手写 PHP MVC 框架(40节精讲/巨细/新人进阶必看)

    相关文章推荐

    • ❤️‍🔥共22门课程,总价3725元,会员免费学• ❤️‍🔥接口自动化测试不想写代码?• mysql 数据备份类代码• PHP类中的魔术方法(Magic Method)简明总结,magicmethod• 第十节--抽象方法和抽象类 -- Classes and Objects in PHP5 [10]• php mysql 数据库类• php 树型结构操作类代码(1/4)
    1/1

    PHP中文网