技术开发 频道

PHP开发者必须了解的9个魔术方法

  __set

  那么,我们将所有对 $this->name 的调用都更改为返回 $this->username的值,那么,如果我们想要设置这个值呢?也许我们有一个账户界面允许用户修改他们的名字。这时我们就需要 __set 方法的帮助了,举例说明:

class Penguin extends Animal {

  
public function __construct($id) {
    
$this->getPenguinFromDb($id);
  }

  
public function getPenguinFromDb($id) {
    
// elegant and robust database code goes here
  }

  
public function __get($field) {
    
if($field == 'name') {
      
return $this->username;
    }
  }

  
public function __set($field, $value) {
    
if($field == 'name') {
      
$this->username = $value;
    }
  }
}

  这样,我们就针对大量的调用伪造对象的属性,正如我说的,这并不是一个正统的方法,但却是一个很有用的技巧,值得记住。

  __call

  这里有两种近似的方法,我并没有单独列出来,而是一起说明。一个是 _call 方法,如果定义,它将在调用未定义过的方法时被调用;另一个是 _callStatic 方法,工作方式与第一个相同,但却是在调用未定义的静态方法时生效(PHP 5.3 加入).通常我使用 __call 进行友善的错误处理,这在需要别人整合调用你的方法的库代码中非常有用。例如,如果一段脚本拥有一个企鹅对象,名为 $penguin ,它包含一个 $penguin->speak() 方法...假设 speak() 方法没有定义,那么正常情况下我们会看到:

  通过定义 __call 方法,我们可以使用一些更友善的提示信息来代替PHP的错误提示:

class Animal {
}
class Penguin extends Animal {

  
public function __construct($id) {
    
$this->getPenguinFromDb($id);
  }

  
public function getPenguinFromDb($id) {
    
// elegant and robust database code goes here
  }

  
public function __get($field) {
    
if($field == 'name') {
      
return $this->username;
    }
  }

  
public function __set($field, $value) {
    
if($field == 'name') {
      
$this->username = $value;
    }
  }

  
public function __call($method, $args) {
      
echo "unknown method " . $method;
      
return false;
  }
}

  这将捕获的错误并回应。在实际应用中,更合适的方法是依据你的需要纪录消息日志·,将用户重定向,或者抛出一个异常,但概念是相同的。在这里你可以处理任何你需要处理的不当调用,你可以检测方法的名称,并一一处理——例如,你可以同上面我们重命名属性一些样重命名方法。

  __sleep

  __sleep()方法会被调用当对象被序列化后,并允许你处理序列化。这有各种各样的程序,一个很好的例子如果一个对象包含某种类型的指针,例如文件句柄或引用另一个对象。当对象被序列化然后解序列化,这些引用类型是无用的,因为这些类型的引用的目标可能不再存在或有效。因此,最好是来取消这些信息在存储它们之前。

  __wakeup

  __wakeup()是与__sleep()方法相反的,允许您更改对象解序列化的行为。和__sleep()一起使用,可以用来恢复被删除的句柄和对象当对象被序列化时。一个很好的例子程序是数据库句柄被取消设置当该项被序列化,然后恢复到当前配置中设置项目时,解序列化一个数据库句柄。

0
相关文章