background image

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() 方法没有

定义,那么正常情况下我们会看到: