PHP的魔术变量及魔术方法
来源:互联网 发布:商业数据网站 编辑:程序博客网 时间:2024/04/27 21:43
有八个魔术常量它们的值随着它们在代码中的位置改变而改变。
__LINE__
__FILE__
__DIR__
__FUNCTION__
__CLASS__
__TRAIT__
__METHOD__
__NAMESPACE__
PHP 中的 9 个魔术方法
这些'魔术'方法拥有者特殊的名字,以两个下划线开始,表示这些方法在php特定事件下将会被触发。这可能听起来有点自动魔法但是它真的很酷的,我们已经看过一个简单的例子在last post,即我们使用一个构造器-使用这个作为我们第一个例子
__construct
构造器是一个魔术方法,当对象被实例化时它会被调用。在一个类声明时它常常是第一件做的事但是没得必要他也像其他任何方法在类中任何地方都可以声明,构造器也能像其他方法样继承。如果我们想到以前继承例子从介绍到oop,我们能添加构造方法到Animal 类中,如:
1
class
Animal{
2
3
public
function
__construct() {
4
$this
->created = time();
5
$this
->logfile_handle =
fopen
(
'/tmp/log.txt'
,
'w'
);
6
}
7
8
}
1
class
Penguin
extends
Animal {
2
3
}
4
5
$tux
=
new
Penguin;
6
echo
$tux
->created;
__destruct
你发现文件句柄也是构造器一部分吗?当我们使用完一个对象时真不想把事情放一边,因此析构方法做着与构造方法相反的事情。当对象被销毁时,析构方法会运行,或者明确的说当我们不再使用它时,php会为我们清理掉。Animal类中,我们的析构方法像这样,如:
01
class
Animal{
02
03
public
function
__construct() {
04
$this
->created = time();
05
$this
->logfile_handle =
fopen
(
'/tmp/log.txt'
,
'w'
);
06
}
07
08
public
function
__destruct() {
09
fclose(
$this
->logfile_handle);
10
}
11
}
__get
这个魔术方法是一个非常灵巧的小技巧 - 它使实际上不存在的属性如同存在一半。让我们举个小企鹅的例子:
01
class
Penguin
extends
Animal {
02
03
public
function
__construct(
$id
) {
04
$this
->getPenguinFromDb(
$id
);
05
}
06
07
public
function
getPenguinFromDb(
$id
) {
08
// elegant and robust database code goes here
09
}
10
}
现在,如果我们的小企鹅有一个 "name" 属性,而在此之后加载的属性为 "age",那么我们可以这样处理:
1
$tux
=
new
Penguin(3);
2
echo
$tux
->name .
" is "
.
$tux
->age .
" years old\n"
;
然而,设想一下,后端数据库或数据供应者发生了改变,"name"没有了,变味了"username"。并且设想这是一个非常复杂的应用,而需要修改的调用"name"的地方非常多。我们可以使用 __get 方法,使得"name"属性如同存在一样:
01
class
Penguin
extends
Animal {
02
03
public
function
__construct(
$id
) {
04
$this
->getPenguinFromDb(
$id
);
05
}
06
07
public
function
getPenguinFromDb(
$id
) {
08
// elegant and robust database code goes here
09
}
10
11
public
function
__get(
$field
) {
12
if
(
$field
==
'name'
) {
13
return
$this
->username;
14
}
15
}
这并不是编写整个系统的好方法,因为它会让调试工作变得更困难,但它是一个非常有价值的工具。它允许如同属性一样使用或者展示需要经过计算的数据,以及无数我都想不到的地方。
__set
那么,我们将所有对 $this->name 的调用都更改为返回 $this->username的值,那么,如果我们想要设置这个值呢?也许我们有一个账户界面允许用户修改他们的名字。这时我们就需要 __set 方法的帮助了,举例说明:
01
class
Penguin
extends
Animal {
02
03
public
function
__construct(
$id
) {
04
$this
->getPenguinFromDb(
$id
);
05
}
06
07
public
function
getPenguinFromDb(
$id
) {
08
// elegant and robust database code goes here
09
}
10
11
public
function
__get(
$field
) {
12
if
(
$field
==
'name'
) {
13
return
$this
->username;
14
}
15
}
16
17
public
function
__set(
$field
,
$value
) {
18
if
(
$field
==
'name'
) {
19
$this
->username =
$value
;
20
}
21
}
22
}
这样,我们就针对大量的调用伪造对象的属性,正如我说的,这并不是一个正统的方法,但却是一个很有用的技巧,值得记住。
__call
这里有两种近似的方法,我并没有单独列出来,而是一起说明。一个是 _call 方法,如果定义,它将在调用未定义过的方法时被调用;另一个是 _callStatic 方法,工作方式与第一个相同,但却是在调用未定义的静态方法时生效(PHP 5.3 加入).通常我使用 __call 进行友善的错误处理,这在需要别人整合调用你的方法的库代码中非常有用。例如,如果一段脚本拥有一个企鹅对象,名为 $penguin ,它包含一个 $penguin->speak() 方法...假设 speak() 方法没有定义,那么正常情况下我们会看到:
PHP Fatal error: Call to undefined method Penguin::speak() in ...
通过定义 __call 方法,我们可以使用一些更友善的提示信息来代替 PHP 的错误提示:
01
class
Animal {
02
}
03
class
Penguin
extends
Animal {
04
05
public
function
__construct(
$id
) {
06
$this
->getPenguinFromDb(
$id
);
07
}
08
09
public
function
getPenguinFromDb(
$id
) {
10
// elegant and robust database code goes here
11
}
12
13
public
function
__get(
$field
) {
14
if
(
$field
==
'name'
) {
15
return
$this
->username;
16
}
17
}
18
19
public
function
__set(
$field
,
$value
) {
20
if
(
$field
==
'name'
) {
21
$this
->username =
$value
;
22
}
23
}
24
25
public
function
__call(
$method
,
$args
) {
26
echo
"unknown method "
.
$method
;
27
return
false;
28
}
29
}
这将捕获的错误并回应。在实际应用中,更合适的方法是依据你的需要纪录消息日志·,将用户重定向,或者抛出一个异常,但概念是相同的。在这里你可以处理任何你需要处理的不当调用,你可以检测方法的名称,并一一处理——例如,你可以同上面我们重命名属性一些样重命名方法。
__sleep
__sleep()方法会被调用当对象被序列化后,并允许你处理序列化。这有各种各样的程序,一个很好的例子如果一个对象包含某种类型的指针,例如文件句柄或引用另一个对象。当对象被序列化然后解序列化,这些引用类型是无用的,因为这些类型的引用的目标可能不再存在或有效。因此,最好是来取消这些信息在存储它们之前。
__wakeup
__wakeup()是与__sleep()方法相反的,允许您更改对象解序列化的行为。和__sleep()一起使用,可以用来恢复被删除的句柄和对象当对象被序列化时。一个很好的例子程序是数据库句柄被取消设置当该项被序列化,然后恢复到当前配置中设置项目时,解序列化一个数据库句柄。
__clone
我们看过一个使用clone关键字的例子,在我的介绍从入门到oop的第二部分,创建对象的副本,而不是有两个变量指向同一个实际的数据。在一个类中重写此方法,我们可以观察发生了什么当在对象上使用clone关键字时,。虽然这是不是我们每一天能遇到的,一个漂亮的用例是创建一个真正的单例模式通过添加private访问修饰符给这个方法。
__toString
无疑把最好的始终留到最后,__toString方法是一个非常方便的附加方法对于我们的工具包。该方法可以声明覆盖对象的行为,当作为一个字符串输出时,例如,当它被输出时。如果你想能输出对象到模板中,你可以使用此方法来控制输出结果。让我们再来看看在Penguin类中:01
class
Penguin {
02
03
public
function
__construct(
$name
) {
04
$this
->species =
'Penguin'
;
05
$this
->name =
$name
;
06
}
07
08
public
function
__toString() {
09
return
$this
->name .
" ("
.
$this
->species .
")\n"
;
10
}
11
}
1
$tux
=
new
Penguin(
'tux'
);
2
echo
$tux
;
更多魔术方法
更多参考 http://php.net, 列出的所有的魔术方法(是的。不仅仅是文中所列出的,我仅仅选出那些我认为最好开始学习的)如果你想了解其他请仔细查看
本文地址:http://www.oschina.net/translate/9-magic-methods-in-php
原文地址:www.lornajane.net/posts/2012/9-magic-methods-in-php
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们
- PHP的魔术变量及魔术方法
- php魔术方法和魔术变量
- php魔术方法和魔术变量
- PHP魔术方法和魔术变量总结
- php魔术方法和魔术变量
- php的魔术变量
- php的魔术方法
- php的魔术方法
- php的魔术方法
- PHP的魔术方法
- PHP的魔术方法
- PHP的魔术方法
- php的魔术方法
- php的魔术方法
- PHP的魔术方法
- PHP的魔术方法
- PHP的魔术方法
- PHP的魔术常量和魔术方法
- UIButton 控制UIImage自由改变大小
- ParentViewController上子ViewController转换时的方法调用顺序
- 决策树
- iOS网络监测如何区分2、3、4G、wifi?
- Objective-C语法之KVC使用
- PHP的魔术变量及魔术方法
- 稳压电路
- 阳光厨房报表改echarts
- Java - 强引用、弱引用、软引用、虚引用
- 敏捷分享 -- 分享会的准备 1
- Mob平台Smssdk获取短信验证码
- Truncate table,Delete From table,与Drop table的区别
- 这些年我用过的编程语言
- 点击Cell进行多控制器跳转的简便写法