您的位置:首页 > 编程语言 > PHP开发

php魔术方法

2010-06-29 11:42 411 查看
从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时调用的,例如

<?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

?>

<?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则是访问和设置类不存在的成员变量时调用的。

这三个的函数原型如下:

mixed __call(string
$name
,
array

$arguments
)

void __set(string $name
, mixed
$value
)

mixed __get(string $name
)

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

__call的例子:

<?php

class
Caller

{

public

function
__call(
$method
,
$args
)

{

echo

"Method $method called:/n"
;

print_r($args
);

}

}

$foo
=
new
Caller();

$foo
->test(1, 2);

?>

<?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

?>

<?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其实原理是差不多的,他们的原型如下:

bool __isset(string
$name
)

void __unset(string $name
)

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

举个例子:

<?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
);

?>

<?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这个魔术方法就会调用它。

举例如下:

<?php

class
a

{

public

function
__clone()

{

echo

"object cloned/n"
;

}

}

$a
=
new
a;

$b
=
$a
;
// $b只是$a的引用,
不是克隆,所以不调用__clone,没任何输出。

$c
= clone
$a
;
// 调用了__clone,将输出 object cloned

?>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: