技术开发 频道

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

        【IT168 技术】这个标题有点牵强,因为PHP有不只9种魔术方法, 但是这些将会引导你使用PHP魔术方法一个好的开始。它可能魔幻,但是并不需要魔杖。

  这些'魔术'方法拥有者特殊的名字,以两个下划线开始,表示这些方法在PHP特定事件下将会被触发。这可能听起来有点自动魔法但是它真的很酷的,我们已经看过一个简单的例子在 last post,即我们使用一个构造器-使用这个作为我们第一个例子。

  __construct

  构造器是一个魔术方法,当对象被实例化时它会被调用。在一个类声明时它常常是第一件做的事但是没得必要他也像其他任何方法在类中任何地方都可以声明,构造器也能像其他方法样继承。如果我们想到以前继承例子从介绍到oop,我们能添加构造方法到Animal 类中,如:

class Animal{

  
public function __construct() {
    
$this->created = time();
    
$this->logfile_handle = fopen('/tmp/log.txt', 'w');
  }

}

  现在我们创建一个类来继承Animal类 - Penguin类!不添加任何属性和方法在Penguin类中,我们能申明并定义它继承自Animal类,如:

class Penguin extends Animal {

}

$tux
= new Penguin;
echo $tux
->created;

  如果我们定义一个构造方法在Penguin类中,然后Penguin对象将会运行当它被实例化后。由于并没有构造方法,PHP会参考父类方法定义 信息来使用它因此我们能覆盖父类方法,或者不,在我们的新类中-很便利。

  __destruct

  你发现文件句柄也是构造器一部分吗?当我们使用完一个对象时真不想把事情放一边,因此析构方法做着与构造方法相反的事情。当对象被销毁时,析构方法会运行,或者明确的说当我们不再使用它时,PHP会为我们清理掉。Animal类中,我们的析构方法像这样,如:

class Animal{

  
public function __construct() {
    
$this->created = time();
    
$this->logfile_handle = fopen('/tmp/log.txt', 'w');
  }

  
public function __destruct() {
    
fclose($this->logfile_handle);
  }
}

  析构器让我们关闭任何额外的资源比如被使用过的对象。在PHP中由于我们有这样运行时间短的脚本(留意在更新的PHP版本中增强的垃圾回收机制),通常讨论内存溢出根本不需要。然而它仍是好的推行方法来清理而且总体上让程序运行起来更高效。

  __get

  这个魔术方法是一个非常灵巧的小技巧 - 它使实际上不存在的属性如同存在一半。让我们举个小企鹅的例子:

class Penguin extends Animal {

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

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

  现在,如果我们的小企鹅有一个 "name" 属性,而在此之后加载的属性为 "age",那么我们可以这样处理:

$tux = new Penguin(3);
echo $tux->name . " is " . $tux->age . " years old\n";

  然而,设想一下,后端数据库或数据供应者发生了改变,"name"没有了,变味了"username"。并且设想这是一个非常复杂的应用,而需要修改的调用"name"的地方非常多。我们可以使用 __get 方法,使得"name"属性如同存在一样:

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;
    }
}

  这并不是编写整个系统的好方法,因为它会让调试工作变得更困难,但它是一个非常有价值的工具。它允许如同属性一样使用或者展示需要经过计算的数据,以及无数我都想不到的地方。

0
相关文章