`
isiqi
  • 浏览: 16497612 次
  • 性别: Icon_minigender_1
  • 来自: 济南
社区版块
存档分类
最新评论

PHP中的Magic Methods

阅读更多

下面我将对PHP所有的魔术方法进行介绍说明。其实下面的大多数方法,对于一个合格的PHP程序员来说,都是很熟悉的东西了。我在这里作个总结,自己作个记录学习,同时也给还未熟悉这些方法的同学们做个介绍。如有疏漏和错误,希望各位能指出。下面所提到的,大多数是PHP5所增加的魔术方法,少部分在PHP4里就已经存在,少部分则是PHP5.1.0之后才出现的,这个在下面我将会提到。
__construct()__destruct()
构造函数__construct()和析构函数__destruct(),这两个不用我多说了吧,是个程序员都知道。__construct()会在实例创建的时候被调用,__destruct()在实例销毁的时候被调用。需要注意的时候,即使你不显式地调用unset去销毁一个实例,它也会在脚本运行结束的时候被销毁。这两个方法都可以传递0个或者多个参数。
<?php
class o
{
publicfunction __construct()
{
echo 'building instance';
}
publicfunction __destruct()
{
echo 'destroy instance';
}
}
$i = new o;
unset($i);//这句有无都不影响最后的输出。__destruct()总是会被调用的
//输出
//building instance
//destroy instance
?>
__get, __set, __isset, __unset
当对一个属性进行操作的时候,如果该属性不可获得(不存在,或者当前环境不可调用该属性,例如在子类中调用一个父类的private属性),则调用以上方法的其中一个。调用什么方法是依据对属性所进行的操作。注:在php 5.0.*里,这4个方法必须为public
__get
触发事件:调用属性
参数 1 :所调用的属性名
例子:
<?php
class o
{
protected function __get($var)
{
return'No Member:'.$var;
}
}
$i=new o();
echo $i->name; // 输出 No Member:name
?>
<?php
class o
{
private $name='surfchen';//注意这里的private
protected function __get($var)
{
return'No Member:'.$var;
}
}
class child extends o
{
function test()
{
echo $this->name;
}
}
$c=new child();
echo $c->test(); // 输出 No Member:name
?>
__set
触发事件:对一个属性进行赋值
参数 1 :所调用的属性名
参数 2 :所赋予的值
例子:
<?php
class o
{
protected function __set($var,$val)
{
echo 'setting '.$var.' to '.$val."\n";
}
}
$c=new o();
echo $c->name='wolfzeus';
/*
输出:
setting name to wolfzeus
wolfzeus
*/
?>
__isset
触发事件:用isset检测属性是否存在
参数 1 :所调用的属性名
例子:
<?php
class o
{
protected function __isset($var)
{
echo $var.' have not been set';
}
}
$c=new o();
isset($c->name);
/*
输出:name have not been set
*/
?>
__unset
触发事件:unset一个属性(无论这个属性是否存在)
参数 1 :所调用的属性名
例子:
<?php
class o
{
protected function __unset($var)
{
echo $var.' is unset';
}
}
$c=new o();
unset($c->name);
/*
输出:
name is unset
*/
?>
__call($func,$para)
当尝试调用一个对象的方法的时候,如果该方法不存在,则调用__call($func,$para)方法。这个方法必须有两个参数,第一个为调用的方法名,第二个是一个被调用方法的参数数组。需要注意的是,当你在一个子类调用父类的private的方法,或者在实例里调用类的非protect方法的时候,并不会调用__call(),这是__call__get等属性操作方法的一个不同点。
<?php
class o
{
protected function __call($func,$para)
{
echo 'No Method:'.$func."\n".'With Below Parameters:'."\n";
print_r($para);
}
}
$c=new o();
echo $c->getNames('programmer','geek');
/*
输出:
No Method:getNames
With Below Parameters:
Array
(
[0] => programmer
[1] => geek
)
*/
?>
__sleep(), __wakeup()
__sleep
是当序列化(serialize)一个实例的时候被调用,__wakeup()则是在反序列化(unserialize)的时候被调用。需要注意一点,就是__sleep()必须返回一个数组或者对象(一般返回的是$this),返回的值将会被用来做为序列化的值。如果不返回这个值,则序列化失败。这也意味着反序列化将不会触发__wakeup事件。下面是一个可用的例子。
<?php
class o
{
public $a='xx';
public $b='55';
function __sleep()
{
echo "I am sleepy\n";
return $this;
}
function __wakeup()
{
echo "wake up!\n";
}
}
$i = new o;
$si = serialize($i);
echo "sleeping now.....\n";
print_r(unserialize($si));
?>
__toString()
当直接打印一个对象的时候,这个方法将会被调用。
例子:
<?php
class o
{
private $name = 'surfchen';
publicfunction __toString()
{
return $this->name;
}
}
$i = new o;
echo 'name:',$i;//注意这里连接name和变量$i的是逗号而不是句号
?>
__set_state()
var_export
可以把一个集合导出为一串字符串,这些字符串是一些可执行的PHP代码。在php5.1.0的面向对象里,引入了一个叫__set_state的静态方法来使得var_export支持对象实例的导出。当用var_export导出一个实例的时候,所导出字符串里,是调用这个静态方法的代码。这个方法有一个参数,为包含所导出的实例的所有成员属性的一个数组。有点抽象,看下面的例子吧。
<?php
class o
{
public $skill='php';
public static function __set_state($arr)
{
foreach ($arr as $k => $v) {
$obj->$k = $v;
}
return $obj;
}
}
$i = new o;
$i->age = 21;
eval('$b = '.var_export($i,true).';');//这里的true表示var_export返回所导出的字符串,而不是把它打印出来。
print_r($b);
/*
输出:
stdClass Object
(
[skill] => php
[age] => 21
)
*/
?>
__clone()
php5里,对象间的赋值总是以地址引用来传递的。例如下面这个例子,将会输出66,而不是55.
<?php
class o
{
public $age = 55;
}
$i = new o;
$i2 = $i;
$i->age = 66;
echo $i2->age;
?>
如果要以实际值来传递,则需要用到clone关键词。
<?php
class o
{
public $age = 55;
}
$i = new o;
$i2 = clone $i;
$i->age = 66;
echo $i2->age;//输出55
?>
但是,这里clone的只是$i这个实例。如果$i的某个成员属性也是个实例,那么这个成员属性还是会以引用方法被传递到$i2的。例如下面这个例子:
<?php
class o
{
public $age = 55;
public $sub = null;
}
class o2
{
public $p=1;
}
$i = new o;
$i->sub=new o2;
$i2 = clone $i;
$i->sub->p=5;
echo $i2->sub->p;
?>
最后输出的是5,而不是1。也就是说,$i$i2虽然不是指向的虽然不是同一个实例,但是它们的成员属性$sub却是指向同一个实例。这时候,我们必须借助__clone这个方法来对$sub进行复制。在o类里,加入__clone()方法。如下:
<?php
class o
{
public $age = 55;
public $sub = null;
public function __clone()
{
$this->sub=clone $this->sub;
}
}
//......
?>
这样,在echo $i2->sub->p;的时候,输出的就是传递时候的值1了。
__autoload()
当创建一个实例化的时候,如果对应的类不存在,__autoload()将会被执行,这个函数有一个参数,为所要创建的实例对应的类名。在下面的例子里,当创建一个test类的实例的时候,如果/home/surfchen/project/auto.php存在,则require这个文件,否则打印一个Class test Not Found的错误,并中止当前脚本。
<?php
function __autoload($class_name) {
if ($class_name == 'test') {
$class_file = '/home/surfchen/project/auto.php';
}
if (is_file($class_file)) {
require_once $class_file;
return true;
}
echo 'Class '.$class_name.' Not Found';
exit();
}
$o=new test();
echo $o->a;
?>
分享到:
评论

相关推荐

    详解php魔术方法(Magic methods)的使用方法

    PHP 中使用 `serialize()` 和 `unserialize()` 函数来序列化和反序列化对象时,魔术方法 `__sleep()` 和 `__wakeup()` 分别在序列化前后被调用。`__sleep()` 用于在对象序列化之前执行任何必要的操作,比如关闭文件...

    那些年我们错过的魔术方法(Magic Methods)

    __call(),__callStatic(),__get(),__set(),__isset(),__unset(),__sleep(),__wakeup(),__toString(),__invoke(),__set_state() 和 __clone() 等方法在 PHP 中被称为”魔术方法”(Magic methods)。...

    php5帮助文档&php4完全中文手册

    在PHP4的基础上进行了大量的改进和增强,包括类型安全性的提升、面向对象编程的完善、错误处理机制的优化以及新功能的添加,例如:魔术方法(Magic Methods)、异常处理(Exception Handling)、PDO(PHP Data ...

    Mastering PHP 7

    You'll see, in detail, the working of all magic methods, and the importance of effective PHP OOP concepts, which will enable you to write effective PHP code. You will find out how to implement design...

    最好最全的PHP开发手册及教程,PHP5

    同时,魔术方法(Magic Methods)如`__construct`、`__destruct`等,让对象生命周期管理更加灵活。 另外,PHP5中的错误处理机制得到改进,引入了异常处理(Exception Handling)。通过抛出和捕获异常,开发者可以更...

    PHP100视频教程100讲源码

    080和081讲可能涉及到PHP的高级特性,如PHP的命名空间(namespaces)、自动加载(autoloading)和PHP的魔术方法(magic methods),这些都是现代PHP开发中不可或缺的部分,可以提升代码的组织和复用性。 通过学习...

    PHP 5 In Practice

    PHP 5还引入了魔术方法(Magic Methods),如__construct、__destruct、__get、__set等,这些方法在特定情况下自动调用,为开发者提供了更多的控制点。例如,__construct用于对象初始化,而__get和__set则允许动态地...

    深入PHP:面向对象、模式与实践(第三版)高清PDF和完整源码.zip

    在实际开发中,PHP的面向对象编程不仅限于基本概念,还涉及到更多的高级主题,如命名空间(Namespaces)、接口(Interfaces)、抽象类(Abstract Classes)、异常处理(Exception Handling)、魔术方法(Magic ...

    php-5.2.3.tar.gz

    1. **面向对象编程的增强**:在PHP 5.2.x系列中,面向对象编程得到了显著加强,包括支持命名空间(Namespaces)、抽象类(Abstract Classes)、接口(Interfaces)以及魔术方法(Magic Methods)。这些特性为开发者...

    php-5.2.12.tar.gz

    在这一版本中,PHP引入了更强大的类和对象特性,如命名空间(Namespaces)、访问控制(Access Control)的改进,以及魔术方法(Magic Methods)的增强,这些都极大地提高了代码的组织性和可维护性。 其次,PHP ...

    php-5.3.14.tar

    此外,还支持了魔术方法(Magic Methods),如__call()和__get(),增强了类的动态行为。 6. **SPL(Standard PHP Library)** PHP 5.3.14包含SPL库,提供了一系列内置的类和接口,用于处理常见的编程任务,如迭代...

    PHP完全参考手册

    PHP还提供了魔术方法(magic methods),如__construct、__destruct、__get、__set等,这些方法在特定情况下自动调用,可以增强代码的灵活性和可维护性。 除了基本的语法和功能,手册还会涉及数据库操作,尤其是PHP...

    PHP5.2.6源代码

    - 改进了面向对象的特性,比如支持命名空间(Namespaces)、抽象类(Abstract Classes)、接口(Interfaces)以及魔术方法(Magic Methods)。 - 加强了错误处理,如异常处理机制,使得程序能够更优雅地处理错误。...

    PHP历史经典5.2.9 完整版

    此外,还有更好的类继承、抽象类和接口、魔术方法(Magic Methods)以及晚期静态绑定(Late Static Bindings)等功能,极大地提高了代码的可维护性和复用性。 2. **错误处理和异常**:PHP 5引入了面向对象的异常...

    php-5.1.4.tar.gz

    类定义更加灵活,支持魔术方法(magic methods)和访问修饰符(public, private, protected),增强了代码的组织性和可维护性。 2. **PDO(PHP Data Objects)**:5.1.4版本继续强化了PDO,这是一个数据库访问抽象...

    php5 oop编程书

    此外,本书可能还涵盖了接口(Interface)、抽象类(Abstract Class)、魔术方法(Magic Methods)以及异常处理(Exception Handling)等内容。接口定义了一组必须实现的方法,抽象类可以包含抽象方法和非抽象方法,...

Global site tag (gtag.js) - Google Analytics