PHP 魔术函数、魔术常量

来源:互联网 发布:电脑txt小说编辑软件 编辑:程序博客网 时间:2024/04/30 08:50

魔术函数

1。__construct()

实例化对象时被调用,

当__construct和以类名为函数名的函数同时存在时,__construct将被调用,另一个不被调用。

2。__destruct()

当删除一个对象或对象操作终止时被调用。

3。__call()

对象调用某个方法,

若方法存在,则直接调用;

若不存在,则会去调用__call函数。

4。__get()

读取一个对象的属性时,

若属性存在,则直接返回属性值;

若不存在,则会调用__get函数。

5。__set()

设置一个对象的属性时,

若属性存在,则直接赋值;

若不存在,则会调用__set函数。

6。__toString()

打印一个对象的时被调用。如echo$obj;或print $obj;

7。__clone()

克隆对象时被调用。如:$t=newTest();$t1=clone $t;

8。__sleep()

serialize之前被调用。若对象比较大,想删减一点东东再序列化,可考虑一下此函数。

9。__wakeup()

unserialize时被调用,做些对象的初始化工作。

10。__isset()

检测一个对象的属性是否存在时被调用。如:isset($c->name)

11。__unset()

unset一个对象的属性时被调用。如:unset($c->name)

12。__set_state()

调用var_export时,被调用。用__set_state的返回值做为var_export的返回值。

13。__autoload()

实例化一个对象时,如果对应的类不存在,则该方法被调用。

魔术常量

1。__LINE__

返回文件中的当前行号。

2。__FILE__

返回文件的完整路径和文件名。如果用在包含文件中,则返回包含文件名。自PHP 4.0.2 起,__FILE__ 总是包含一个绝对路径,而在此之前的版本有时会包含一个相对路径。

3。__FUNCTION__

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

4。__CLASS__

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

5。__METHOD__

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

 

 

 

什么是魔术函数?

对于__开头的函数就命名为魔术函数,此类函数都在特定的条件下触发的.比如: __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__);// 序列化不成功.没有返回值.反序列也失败 //

returnarray("name"); // 序列化成功.有返回值.反序列成功.id2属性能被恢复 //

returnarray("name", "id2");// 序列化成功.有返回值.反序列成功.id2属性不能被恢复

returnarray("name"); }

public functiontestEcho() {

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 = newtest75();

$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 = newtest75();

$i3 = clone $i2;

$i2->sub->age= 15 ;

var_dump($i3->sub->age);

 

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

复制代码代码如下:

function__autoload($class) {

 if ( $class =="test8" ){

require_oncedirname(__FILE__).'/class8.php'; 

}

}

spl_autoload();

$t8 = new test8;

var_dump($t8->age);

0 0
原创粉丝点击