`
yant
  • 浏览: 18657 次
  • 性别: Icon_minigender_1
  • 来自: 西安
社区版块
存档分类
最新评论

php的魔术方法(转)

    博客分类:
  • php
阅读更多
从php5以后的版本,类就可以使用魔术方法了。php规定以两个下划线(__)开头的方法都保留为魔术方法,所以建议大家函数名最好不用__开头,除非是为了重载已有的魔术方法。

目前php已有的魔术方法有__construct,__destruct,__call,__get,__set,__isset,__unset,__sleep,__wakeup,__toString,__set_state 和 __clone。

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

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


__toString是对象被转为string时调用的,例如

view plaincopy to clipboardprint?
01.<?php  
02.class Str  
03.{  
04.    private $str;  
05. 
06.    public function __construct($str) {  
07.        $this->str = $str;  
08.    }  
09. 
10.    public function __toString() {  
11.        return $this->str;  
12.    }  
13.}  
14. 
15.$class = new Str('Hello');  
16.echo $class; // 这里对象被转为了string,所以调用了__toString  
17.?> 
<?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是当用var_export()来导出类的时候调用的,这个魔术函数只有一个参数,这个参数是一个数组,用来指定export的时候得到的属性。一般很少用到。

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

view plaincopy to clipboardprint?
01.mixed __call(string $name, array $arguments)  
02.void __set(string $name, mixed $value)  
03.mixed __get(string $name) 
mixed __call(string $name, array $arguments)
void __set(string $name, mixed $value)
mixed __get(string $name)
__call的例子:

view plaincopy to clipboardprint?
01.<?php  
02.class Caller  
03.{  
04.    public function __call($method, $args)  
05.    {  
06.        echo "Method $method called:\n";  
07.        print_r($args);  
08.    }  
09.}  
10. 
11.$foo = new Caller();  
12.$foo->test(1, 2);  
13.?> 
<?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 的例子:

view plaincopy to clipboardprint?
01.<?php  
02.class a  
03.{  
04.    public $c = 0;  
05.    public $arr = array();  
06.      
07.    public function __set($k, $v)  
08.    {  
09.        echo $k . "\n";          
10.        echo $v . "\n";  
11.          
12.        $this->arr[$k] = $v;  
13.    }  
14.      
15.    public function __get($k)  
16.    {  
17.        echo "The value of $k is " . $this->arr[$k];  
18.    }  
19.}  
20.$a = new a;  
21.$a->b = 1; // 成员变量b不存在,所以会调用__set  
22.$a->c = 2; // 成员变量c是存在的,所以不调用__set,无任何输出  
23.$d = $a->b; // 成员变量b不存在,所以会调用__get  
24.?> 
<?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这两个与__get和__set其实原理是差不多的,他们的原型如下:

view plaincopy to clipboardprint?
01.bool __isset(string $name)  
02.void __unset(string $name) 
bool __isset(string $name)
void __unset(string $name)
举个例子:

view plaincopy to clipboardprint?
01.<?php  
02.class a  
03.{      
04.    public $c = 3;  
05.    public $arr = array('a' => 1, 'b' => 2);  
06.      
07.    public function __isset($k)  
08.    {  
09.        return isset($this->arr[$k]);  
10.    }  
11.      
12.    public function __unset($k)  
13.    {  
14.        unset($this->arr[$k]);  
15.    }  
16.}  
17.$a = new a;  
18. 
19.var_dump(isset($a->a)); // 成员变量a不存在,所以调用__isset,返回true  
20.var_dump(isset($a->c)); // 成员变量c是存在的,没有调用__isset,同样返回true  
21.unset($a->b); // 成员变量b不存在,调用__unset  
22.var_dump($a);  
23.?> 
<?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);
?>
上例将输出:
bool(true)
bool(true)
object(a)#1 (2) {
["c"]=>
int(3)
["arr"]=>
array(1) {
    ["a"]=>
    int(1)
}
}

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

view plaincopy to clipboardprint?
01.<?php  
02.class a  
03.{      
04.    public function __clone()  
05.    {  
06.        echo "object cloned\n";  
07.    }  
08.}  
09.$a = new a;  
10. 
11.$b = $a; // $b只是$a的引用,不是克隆,所以不调用__clone,没任何输出。  
12.$c = clone $a; // 调用了__clone,将输出 object cloned  
13.?> 
分享到:
评论

相关推荐

    PHP 魔术方法整理

    魔术方法:魔术函数是PHP中内置的语言特性,当程序执行到某种情况时,如果定义了这些魔术函数 (php手册中称之为“Overloading”),则PHP会调用他们,同时也会传入相应的参数,可以认为是PHP执行过程中的钩子函数

    16种魔术方法

    php 概念性知识,全面的魔术方法,不用再找,收藏直接看

    php中的常用魔术方法汇总

    这篇文章详细的对php中的常用魔术方法进行了整理归纳,分享给大家供大家参考,具体内容如下 1、PHP把所有”__”开头的方法当做魔术方法,所以任何自定义的方法都不能是”__”开头 php提供的重载,是指动态的创建属性...

    php 魔术函数和常量一览表

    php 魔术函数和常量一览表

    PHP中的常见魔术方法功能作用及用法实例

    在面向对象编程中,PHP提供了一系列的魔术方法,这些魔术方法为编程提供了很多便利。PHP中的魔术方法通常以__(两个下划线)开始,并且不需要显示的调用而是由某种特定的条件出发。这篇文章简单总结了PHP中提供的魔术...

    PHP之十六个魔术方法详细介绍

    PHP中把以两个下划线__开头的方法称为魔术方法(Magic methods),这些方法在PHP中充当了举足轻重的作用。 魔术方法包括: __construct(),类的构造函数 __destruct(),类的析构函数 __call(),在对象中调用一个不...

    php 魔术方法使用说明

    一些在PHP叫魔术方法的函数,在这里介绍一下:其实在一般的应用中,我们都需要用到他们!!1.__construct() 当实例化一个对象的时候,这个对象的这个方法首先被调用。 Java代码 class Test { function __construct...

    魔术贴网站源码PHP源码.zip

    魔术贴网站源码PHP源码.zip

    基于PHP5魔术常量与魔术方法的详解

    魔术常量:1。__LINE__返回文件中的当前行号。2。__FILE__ 返回文件的完整路径和文件名。如果用在包含文件中,则返回包含文件名。自PHP4.0.2 起,__FILE__总是包含一个绝对路径,而在此之前的版本有时会包含一个...

    php魔术方法与魔术变量、内置方法与内置变量的深入分析

    本篇文章是对php魔术方法与魔术变量、内置方法与内置变量进行了详细的分析介绍,需要的朋友参考下

    计算机后端-PHP视频教程. php之面向对象20 魔术方法的意义.wmv

    计算机后端-PHP视频教程. php之面向对象20 魔术方法的意义.wmv

    php 魔术方法详解

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

    PHP 预定义变量、魔术常量和魔术方法功能与用法小结

    本文总结了PHP 预定义变量、魔术常量和魔术方法。分享给大家供大家参考,具体如下: PHP 预定义了一些变量、常量、方法,使用起来很方便,例如直接使用 __DIR__ 获取当前文件所在的目录。 下面分别详细介绍一下 PHP...

    php中的常用魔术方法总结

    常用的魔术方法有:__Tostring () __Call() __autoLoad() __ clone() __GET() __SET() __isset() __unset() 1.__Tostring() 用于定义输出对象引用时调用 常用于打印一些对象的信息 必须有返回值eg:有一个...

    php代码-魔术方法php

    php代码-魔术方法php

    PHP魔术常量及魔术函数.doc

    常用的php魔术常量和魔术函数,有时候使用魔术函数挺方便的。

    PHP魔术方法使用方法汇总

    魔术方法是PHP面向对象中特有的特性。它们在特定的情况下被触发,都是以双下划线开头,你可以把它们理解为钩子,利用模式方法可以轻松实现PHP面向对象中重载(Overloading即动态创建类属性和方法)。魔术方法很多...

Global site tag (gtag.js) - Google Analytics