探秘php中的魔术方法

在面向对象的编程中,php为我们提供很多魔术方法,灵活的使用这些魔术方法,可以简化我们在面向对象开发过程中的很多操作。在php中,魔术方法通常都是以两个下划线(__)开头的。与php中的普通方法(方法也称函数)不同的是,魔术方法通常是在特定情况下由程序自动调用的,而普通方法通常是由我们手动调用的。魔术方法为我们提供了非常有用的功能,php中的魔术方法有很多,具体有哪些,大家可以参考下php的手册,在这里即可查看。在本篇文章中,我仅仅为大家简单介绍下一些常用的魔术方法。
一、准备工作
为了充分理解魔术方法的概念,我们就需要在代码中使用下这些魔术方法,只有概念性的东西,估计看过一遍也就忘了。所以这里我们需要先定义两个简单的类。
通常,我们习惯将每个类都定义在一个单独的文件中,类文件以”类名.class.php”的形式命名。这里我们定义两个简单的类一个是device类,一个是battery类。定义的两个类如下所示:
文件:device.class.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

文件:battery.class.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

在device类中,定义了四个成员属性,分别是:name用来表示设备的名称,battery用来保存一个battery对象,data被定义为数组,connection用来保存外外部资源的句柄。在该类中,同样定义了两个成员方法connect()和disconnect()分别用来建立和断开连接。
在battery类中,仅仅定义了一个私有属性charge和一个成员方法setcharge()用来设置charge的值。
这里定义的两个类,并没有什么实际的用途,仅仅是为了使大家能够更好的理解php中的魔术方法。
二、构造函数和析构函数
构造函数和析构函数是在对象被创建和销毁时,由系统自动调用的。
1.构造函数:__construct()
__construct函数是目前为止被使用最多的魔术函数。当对象被创建的时候,我们可以在构造函数中进行任何的初始化操作,特别是对成员变量进行初始化操 作。可以为构造函数定义任意数量的参数。无论构造函数出于何种原因不能被正确执行,那么对象的创建就会失败。下面是在device类中使用构造函数的例子。

1
2
3
4
5
6
public function __construct($name,battery $battery){
//battery的值只能是由battery类实例化的一个对象
$this->battery=$battery;
$this->name=$name;
$this->connect();
}

在这个构造函数中,我们为构造函数指定了两个形参,分别为成员属性name和battery赋值,同时在构造函数中还调用了该类的connect()函数。
注意:将构造函数声明为私有方法可以阻止程序在类外部直接创建该类的一个实例对象,这在实现设计模式的单例模式时很常用。
有了构造函数,我们可以像下面的代码一样实例化一个device类的对象。

1
$device=new device(‘iphone’,$battery);

2.析构函数:__destruct()
与构造函数相反,析构函数是在对象被销毁时由系统自动调用的。在类中定义构造函数的方式如下:

1
2
3
public function __destruct(){
$this->disconnect();
}

在这个析构函数中,在对象被销毁之前,析构器先调用了类中的disconnect()函数。
三、属性重载
根据php手册中的说明,php所提供的”重载”(overloading)是指动态地”创建”类属性和方法。我们是通过魔术方法(magic methods)来实现的。
当调用当前环境下未定义或不可见的类属性或方法时,重载方法会被调用,换句话说,当访问一个类中可访问的方法或属性时,重载方法不会被调用。所有的重载方法都必须被声明为 public。
1.__get()
当读取不可访问属性的值时,__get() 会被调用。
2.__set()
在给不可访问属性赋值时,__set() 会被调用。
3.__isset()
当对不可访问属性调用 isset() 或 empty() 时,__isset() 会被调用。
4.__unset()
当对不可访问属性调用 unset() 时,__unset() 会被调用。
四、将对象转换为字符串:__tostring()
在我们试图将对象当做一个普通字符串来对待时,__tostring方法会被调用。比如,当我们打印一个对象时,就会自动调用该函数,如:echo $对象名,如果没有定义__tostring方法,那么php将返回一个错误。
五、克隆对象:__clone()
当我们克隆一个对象时,魔术方法__clone()会被自动调用
六、对象序列化
序列化是将任何数据转化为字符串格式的一个过程。通过序列化,我们可以将一个完整的对象保存在一个文件或者保存在数据库中。有关序列化的一个问题是,并不是所有的数据都可以被序列化,例如一个数据库连接。
1.__sleep()
当我们对一个对象使用serialize()函数时,__sleep()函数会被调用。
2.__wakeup()
当我们对一个对象使用unserialize()函数时,__wakeup()函数会被调用。
七、方法重载
1.__call()
在对象中调用一个不可访问方法时,__call() 会被调用。
2.__callstatic() (php 5.3)
用静态方式中调用一个不可访问方法时,__callstatic() 会被调用。
八、将对象当作函数使用
1.__invoke
当我们试图将对象当做函数来使用时,该方法会被调用。
九、自动加载类
1.__autoload()
该方法是我们在实例化一个类时,允许程序自动寻找类文件,并将类文件加载到当前脚本,可以简化很多我们对require的使用。

http://www.bkjia.com/phpjc/621604.htmlwww.bkjia.comtruehttp://www.bkjia.com/phpjc/621604.htmltecharticle在面向对象的编程中,php为我们提供很多魔术方法,灵活的使用这些魔术方法,可以简化我们在面向对象开发过程中的很多操作。在php中,…

Posted in 未分类