zoukankan      html  css  js  c++  java
  • PHP魔术方法和魔术变量总结

    php5以后的版本,类就可以使用魔术方法了PHP规定以两个下划线开头的方法都保留为魔术方法,所以建议大家函数名最好不用__开 头,除非是为了重载已有的魔术方法。

    目前php已有的魔术方法有

    __construct,__destruct,__call,__get,__set,__isset,__unset,__sleep,__wakeup,__toString,__set_state 和 __clone。

    __construct和__destruct

    __construct和__destruct是类的构造函数和析构函数,这个大家经常会用到,相信大家都很熟悉,这里就不多说了。

    __sleep和__wakeup

    __sleep和__wakeup是序列化类的时候调用的。当序列化对象时,php将试图在序列动作之前调用该对象的成员函数__sleep(), 当使用unserialize() 恢复对象时, 将调用__wakeup()。

    __toString

    __toString是对象被转为string时调用必须有返回值即:return xxx ; 否则报错,例如

    <?php  
    class Str  
    {  
        private $str;  
    
        public function __construct($str) {  
            $this->str = $str;  
        }  
    
        public function __toString() {  
            return $this->str;  
        }  
    }  
    
    $class = new Str('Hello');  
    echo $class; // 这里对象被转为了string,所以调用了__toString  
    ?>  

    上例将输出 Hello

    __set_state

    __set_state是当用var_export()来导出类的时候调用的,这个魔术函数只有一个参数,这个参数是一个数组,用来指定 export的时候得到的属性。一般很少用到。

    __call, __get和__set

    __call, __get和__set 这三个魔术方法是最常用的当调用类中不存在的方法时就会调用__call,而__get和__set则是访问和设置类不存在的成员变量时调用的。
    这三个的函数原型如下:

    mixed __call(string $name, array $arguments)  
    void __set(string $name, mixed $value)  
    mixed __get(string $name) 
    • 1

    __call的例子:

    <?php  
    class  Caller  
    {  
        public   function  __call( $method ,  $args )  
        {  
            echo   "Method $method called:/n" ;  
            print_r($args );  
        }  
    }  
    
    $foo  =  new  Caller();  
    $foo ->test(1, 2);  
    ?> 

    上例将输出:
    Method test called:
    Array
    (
    [0] => 1
    [1] => 2
    )

    __get 和 __set 的例子:

    <?php  
    class a  
    {  
        public $c = 0;  
        public $arr = array();  
    
        public function __set($k, $v)  
        {  
            echo $k . "/n";          
            echo $v . "/n";  
    
            $this->arr[$k] = $v;  
        }  
    
        public function __get($k)  
        {  
            echo "The value of $k is " . $this->arr[$k];  
        }  
    }  
    $a = new a;  
    $a->b = 1; // 成员变量b不存在,所以会调用__set  
    $a->c = 2; // 成员变量c是存在的,所以不调用__set,无任何输出  
    $d = $a->b; // 成员变量b不存在,所以会调用__get  
    ?>  

    上例将输出:
    b
    1
    The value of b is 1

    __isset和__unset

    __isset和__unset这两个与__get和__set其实原理是差不多的,他们的原型如下:

    bool __isset(string $name)  
    void __unset(string $name)  
    • 1

    举个例子:

    <?php  
    class  a  
    {      
        public   $c  = 3;  
        public   $arr  =  array ( 'a'  => 1,  'b'  => 2);  
    
        public   function  __isset( $k )  
        {  
            return  isset( $this ->arr[ $k ]);  
        }  
    
        public   function  __unset( $k )  
        {  
            unset($this ->arr[ $k ]);  
        }  
    }  
    $a  =  new  a;  
    
    var_dump(isset($a ->a));  // 成员变量a不存在,所以调用__isset,返回true   
    var_dump(isset($a ->c));  // 成员变量c是存在的,没有调用__isset,同样返回true   
    unset($a ->b);  // 成员变量b不存在,调用__unset   
    var_dump($a );  
    ?>  
    • 1

    上例将输出:

    bool(true)
    bool(true)
    object(a)#1 (2) {
        ["c"]=>int(3)
        ["arr"]=>array(1) {
             ["a"]=>int(1)
        }
    }

    __clone

    类复制(clone)的时候,如果有定义__clone这个魔术方法就会调用它。

    举例如下:

    <?php  
    class  a  
    {      
        public   function  __clone()  
        {  
            echo   "object cloned" ;  
        }  
    }  
    $a  =  new  a;  
    
    $b  =  $a ;  // $b只是$a的引用, 不是克隆,所以不调用__clone,没任何输出。   
    $c  = clone  $a ;  // 调用了__clone,将输出 object cloned   
    ?>  
    • 1上例将输出:

    object cloned

    参考: http://php.net/manual/zh/language.oop5.magic.php

    PHP的魔术常量

    定义: 以两个_开头和结尾的常量为魔术常量
    注意: 魔术常量不区分大小写

    <?php
    $file1 = __FILE__;
    $file2 = __file__;
    var_dump($file1);
    var_dump($file2);
    ?>

    结果是:
    string(36) “F:Apachewww empphp_demo emp.php”
    string(36) “F:Apachewww empphp_demo emp.php”

    _LINE_

    文件中的当前行号。

    _FILE_

    文件的完整路径和文件名。如果用在被包含文件中,则返回被包含的文件名。自 PHP 4.0.2 起,FILE 总是包含一个绝对路径(如果是符号连接,则是解析后的绝对路径),而在此之前的版本有时会包含一个相对路径。

    _DIR_

    文件所在的目录。如果用在被包括文件中,则返回被包括的文件所在的目录。它等价于 dirname(FILE)。除非是根目录,否则目录中名不包括末尾的斜杠。(PHP 5.3.0中新增)

    _FUNCTION_

    函数名称(PHP 4.3.0 新加)。自 PHP 5 起本常量返回该函数被定义时的名字(区分大小写)。在 PHP 4 中该值总是小写字母的。

    _CLASS_

    类的名称(PHP 4.3.0 新加)。自 PHP 5 起本常量返回该类被定义时的名字(区分大小写)。在 PHP 4 中该值总是小写字母的。类名包括其被声明的作用区域(例如 FooBar)。注意自 PHP 5.4 起 CLASS 对 trait 也起作用。当用在 trait 方法中时,CLASS 是调用 trait 方法的类的名字。

    _NAMESPACE_

    当前命名空间的名称(区分大小写)。此常量是在编译时定义的(PHP 5.3.0 新增)。

    _TRAIT_

    Trait 的名字(PHP 5.4.0 新加)。自 PHP 5.4 起此常量返回 trait 被定义时的名字(区分大小写)。Trait 名包括其被声明的作用区域(例如 FooBar)。

    _METHOD_

    类的方法名(PHP 5.0.0 新加)。返回该方法被定义时的名字(区分大小写)。

  • 相关阅读:
    剑指offer二十九---最小的k个数
    Select2插件 点击、选中事件 解读
    Datatable插件的简单的使用方式 和 学习方式
    java map获取值方式
    mysql delete语句使用别名报错
    springmvc 添加@ResponseBody
    maven 创建后报错
    nodejs
    gulp
    Nodejs-express 4.0框架 简单介绍
  • 原文地址:https://www.cnblogs.com/ghjbk/p/6963684.html
Copyright © 2011-2022 走看看