PHP魔术方法须知

参考PHP手册:魔术方法

1.__construct([ mixed $args [, $... ]] )

具有构造函数的类会在每次创建新对象时先调用此方法,用在使用对象之前做一些初始化工作。

Note:
1.如果子类中定义了构造函数则不会隐式调用其父类的构造函数。要执行父类的构造函数,需要在子类的构造函数中调用 parent::__construct()。
2.如果子类没有定义构造函数则会如同一个普通的类方法一样从父类继承(假如没有被定义为 private 的话)。
3.可以为构造函数定义任意多个参数,只要在实例化时传入对应个数的参数即可。构造函数中出现的任何异常都会阻止对象的创建。
4.将构造函数声明为私有方法,可以防止在类外部创建对象,这在单利模式中经常使用。

2.__destruct ( void )

析构函数会在到某个对象的所有引用都被删除或者当对象被显式销毁时执行。

Note:
1.和构造函数一样,父类的析构函数不会被引擎暗中调用。要执行父类的析构函数,必须在子类的析构函数体中显式调用 parent::__destruct()。此外也和构造函数一样,子类如果自己没有定义析构函数则会继承父类的。
2.析构函数即使在使用exit()终止脚本运行时也会被调用。在析构函数中调用exit()将会中止其余关闭操作的运行。
3.析构函数在脚本关闭时调用,此时所有的 HTTP 头信息已经发出。脚本关闭时的工作目录有可能和在 SAPI(如 apache)中时不同。
4.试图在析构 函数(在脚本终止时被调用)中抛出一个异常会导致致命错误。

PHP所提供的"重载"(overloading)是指动态地"创建"类属性和方法。我们是通过魔术方法(magic methods)来实现的。

3.__call、__callStatic(方法重载)

public mixed __call ( string $name , array $arguments )
public static mixed __callStatic ( string $name , array $arguments )

在对象中调用一个不可访问方法时,__call() 会被调用。
在静态上下文中调用一个不可访问方法时,__callStatic()会被调用。

说明:
1.$name 参数是要调用的方法名称。
2.$arguments 参数是一个枚举数组,包含着要传递给方法 $name 的参数。
3.PHP 5.3.0版本新增 __callStatic()魔术方法。可见性未设置为 public 或未声明为 static 的时候会产生一个警告。

4.__set、__get、__isset、__unset

public void __set ( string $name , mixed $value )
在给不可访问属性赋值时,__set() 会被调用。

public mixed __get ( string $name )
读取不可访问属性的值时,__get()会被调用。

public bool __isset ( string $name )
当对不可访问属性调用 isset()empty()时,__isset()会被调用。

public void __unset ( string $name )
当对不可访问属性调用 unset()时,__unset() 会被调用。

说明:
1.参数$name是指要操作的变量名称。__set()方法的$value参数指定了 $name 变量的值。
2.属性重载只能在对象中进行。在静态方法中,这些魔术方法将不会被调用。所以这些方法都不能被 声明为 static。从 PHP 5.3.0 起, 将这些魔术方法定义为 static 会产生一个警告。
3.PHP 5.3.0 新增 __isset()__unset() 两个魔术方法。

Note:
1.因为 PHP 处理赋值运算的方式,__set() 的返回值将被忽略。类似的, 在下面这样的链式赋值中,__get() 不会被调用:$a = $obj->b = 8;

class TestClass
{
    private $foo;

    public function __set($name, $value){
        echo "__set().".$name.".".$value;
    }
    public function __get($get){
        echo "__get({$get})";
    }
}

$class = new TestClass();
$a = $class->foo;
$a = $class->foo = 8;

//输出:
//__get(foo)
//__set().foo.8

Note:
2.在除 isset() 外的其它语言结构中无法使用重载的属性,这意味着当对一个重载的属性使用 empty() 时,重载魔术方法将不会被调用。为避开此限制,必须将重载属性赋值到本地变量再使用 empty()(很遗憾,这个不知道啥意思,如果有人看到,并且知道,深切的恳请告知,Q1563659827,先谢过!(*^__^*) )

5.__sleep()、__wakeup()

public array __sleep ( void )
方法常用于提交未提交的数据,或类似的清理操作。同时,如果有一些很大的对象,但不需要全部保存,这个功能就很好用。

void __wakeup ( void )
经常用在反序列化操作中,例如重新建立数据库连接,或执行其它初始化操作。

6.__toString()

public string __toString ( void )
用于一个类被当成字符串时应怎样回应。例如 echo $obj; 应该显示些什么。此方法必须返回一个字符串,否则将发出一条E_RECOVERABLE_ERROR 级别的致命错误。

7.__invoke()

mixed __invoke ([ $... ] )
当尝试以调用函数的方式调用一个对象时,__invoke()方法会被自动调用。

Note:
本特性只在 PHP 5.3.0 及以上版本有效。

8.__set_state()

static object __set_state ( array $properties )
自 PHP 5.1.0 起当调用 var_export() 导出类时,此方法会被调用。
本方法的唯一参数是一个数组,其中包含按 array('property' => value, ...) 格式排列的类属性。

9.__debugInfo

array __debugInfo ( void )
该方法在var_dump()类对象的时候被调用,如果没有定义该方法,则var_dump会打印出所有的类属性

10.__clone()

对象复制可以通过 clone 关键字来完成(如果可能,这将调用对象的 __clone() 方法)。对象中的 __clone() 方法不能被直接调用。

$copy_of_object = clone $object;

当对象被复制后,PHP 5 会对对象的所有属性执行一个浅复制(shallow copy)。所有的引用属性 仍然会是一个指向原来的变量的引用。

void __clone ( void )

当复制完成时,如果定义了 __clone() 方法,则新创建的对象(复制生成的对象)中的 __clone()方法会被调用,可用于修改属性的值(如果有必要的话)。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,937评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,503评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,712评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,668评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,677评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,601评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,975评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,637评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,881评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,621评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,710评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,387评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,971评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,947评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,189评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,805评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,449评论 2 342

推荐阅读更多精彩内容

  • 一、数组 1、数组定义 数组就是一个键值对组成的语言结构,键类似于酒店的房间号,值类似于酒店房间里存储的东西。 $...
    空谷悠阅读 803评论 4 11
  • 参考资料:PHP5 权威编程 PHP 中的类和对象 对象:万物皆对象; 类: 任何对象,都...
    _1633_阅读 742评论 0 4
  • PHP中的魔术方法总结 :__construct, __destruct , __call, __callStat...
    bycall阅读 595评论 0 0
  • 一、数组 1、数组的声明:$arr = array(); 2、数组的初始化:PHP有两种数组:索引数组、关联数组。...
    yzw12138阅读 1,191评论 2 2
  • 耿耿星河未曙天。 从不学习的路星河,可以因为文中一句“耿耿星河未曙天”背下整篇《长恨歌》;去北京做...
    南天九茴阅读 538评论 1 3