从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手册中称之为“Overloading”),则PHP会调用他们,同时也会传入相应的参数,可以认为是PHP执行过程中的钩子函数
php 概念性知识,全面的魔术方法,不用再找,收藏直接看
这篇文章详细的对php中的常用魔术方法进行了整理归纳,分享给大家供大家参考,具体内容如下 1、PHP把所有”__”开头的方法当做魔术方法,所以任何自定义的方法都不能是”__”开头 php提供的重载,是指动态的创建属性...
php 魔术函数和常量一览表
在面向对象编程中,PHP提供了一系列的魔术方法,这些魔术方法为编程提供了很多便利。PHP中的魔术方法通常以__(两个下划线)开始,并且不需要显示的调用而是由某种特定的条件出发。这篇文章简单总结了PHP中提供的魔术...
PHP中把以两个下划线__开头的方法称为魔术方法(Magic methods),这些方法在PHP中充当了举足轻重的作用。 魔术方法包括: __construct(),类的构造函数 __destruct(),类的析构函数 __call(),在对象中调用一个不...
一些在PHP叫魔术方法的函数,在这里介绍一下:其实在一般的应用中,我们都需要用到他们!!1.__construct() 当实例化一个对象的时候,这个对象的这个方法首先被调用。 Java代码 class Test { function __construct...
魔术贴网站源码PHP源码.zip
魔术常量:1。__LINE__返回文件中的当前行号。2。__FILE__ 返回文件的完整路径和文件名。如果用在包含文件中,则返回包含文件名。自PHP4.0.2 起,__FILE__总是包含一个绝对路径,而在此之前的版本有时会包含一个...
本篇文章是对php魔术方法与魔术变量、内置方法与内置变量进行了详细的分析介绍,需要的朋友参考下
计算机后端-PHP视频教程. php之面向对象20 魔术方法的意义.wmv
从PHP 5以后的版本,PHP中的类就可以使用魔术方法了。其规定以两个下划线(__)开头的方法都保留为魔术方法,所以建议大家函数名最好不用__开头,除非是为了重载已有的魔术方法。PHP 将所有以 _ _(两个下划线)开头的...
本文总结了PHP 预定义变量、魔术常量和魔术方法。分享给大家供大家参考,具体如下: PHP 预定义了一些变量、常量、方法,使用起来很方便,例如直接使用 __DIR__ 获取当前文件所在的目录。 下面分别详细介绍一下 PHP...
常用的魔术方法有:__Tostring () __Call() __autoLoad() __ clone() __GET() __SET() __isset() __unset() 1.__Tostring() 用于定义输出对象引用时调用 常用于打印一些对象的信息 必须有返回值eg:有一个...
php代码-魔术方法php
常用的php魔术常量和魔术函数,有时候使用魔术函数挺方便的。
魔术方法是PHP面向对象中特有的特性。它们在特定的情况下被触发,都是以双下划线开头,你可以把它们理解为钩子,利用模式方法可以轻松实现PHP面向对象中重载(Overloading即动态创建类属性和方法)。魔术方法很多...