当前位置:首页 > PHP教程 > php面向对象 > 列表

详解php魔术方法(Magic methods)的使用方法

发布:smiling 来源: PHP粉丝网  添加日期:2021-07-09 22:53:02 浏览: 评论:0 

有些东西如果不是经常使用,很容易忘记,比如魔术方法和魔术常量,这篇文章主要介绍了php魔术方法(Magic methods)的使用方法,感兴趣的小伙伴们可以参考一下。

PHP中把以两个下划线__开头的方法称为魔术方法,这些方法在PHP中充当了举足轻重的作用。 魔术方法包括:

__construct(),类的构造函数

__destruct(),类的析构函数

__call(),在对象中调用一个不可访问方法时调用

__callStatic(),用静态方式中调用一个不可访问方法时调用

__get(),获得一个类的成员变量时调用

__set(),设置一个类的成员变量时调用

__isset(),当对不可访问属性调用isset()或empty()时调用

__unset(),当对不可访问属性调用unset()时被调用。

__sleep(),执行serialize()时,先会调用这个函数

__wakeup(),执行unserialize()时,先会调用这个函数

__toString(),类被当成字符串时的回应方法

__invoke(),调用函数的方式调用一个对象时的回应方法

__set_state(),调用var_export()导出类时,此静态方法会被调用。

__clone(),当对象复制完成时调用

__construct()和__destruct()

构造函数和析构函数应该不陌生,他们在对象创建和消亡时被调用,例如我们需要打开一个文件,在对象创建时打开,对象消亡时关闭

  1. <?php  
  2. class FileRead 
  3. { 
  4.  protected $handle = NULL; 
  5.  
  6.  function __construct(){ 
  7.   $this->handle = fopen(...); 
  8.  } 
  9.  
  10.  function __destruct(){ 
  11.   fclose($this->handle); 
  12.  } 
  13. } 
  14. ?> 

这两个方法在继承时可以扩展,例如:

  1. <?php  
  2. class TmpFileRead extends FileRead 
  3. { 
  4.  function __construct(){ 
  5.   parent::__construct(); 
  6.  } 
  7.  
  8.  function __destruct(){ 
  9.   parent::__destruct(); 
  10.  } 
  11. } 
  12. ?> 
  13. __call()和__callStatic() 

在对象中调用一个不可访问方法时会调用这两个方法,后者为静态方法,这两个方法我们在可变方法(Variable functions)调用中可能会用到。

  1. <?php 
  2. class MethodTest  
  3. { 
  4.  public function __call ($name, $arguments) { 
  5.   echo "Calling object method '$name' ". implode(', ', $arguments). "\n"; 
  6.  } 
  7.  
  8.  public static function __callStatic ($name, $arguments) { 
  9.   echo "Calling static method '$name' ". implode(', ', $arguments). "\n"; 
  10.  } 
  11. } 
  12.  
  13. $obj = new MethodTest; 
  14. $obj->runTest('in object context'); 
  15. MethodTest::runTest('in static context'); 
  16. ?> 

__get(),__set(),__isset()和__unset()

当get/set一个类的成员变量时调用这两个函数,例如我们将对象变量保存在另外一个数组中,而不是对象本身的成员变量。

  1. <?php  
  2. class MethodTest 
  3. { 
  4.  private $data = array(); 
  5.  
  6.  public function __set($name, $value){ 
  7.   $this->data[$name] = $value; 
  8.  } 
  9.  
  10.  public function __get($name){ 
  11.   if(array_key_exists($name, $this->data)) 
  12.    return $this->data[$name]; 
  13.   return NULL; 
  14.  } 
  15.  
  16.  public function __isset($name){ 
  17.   return isset($this->data[$name]) 
  18.  } 
  19.  
  20.  public function unset($name){ 
  21.   unset($this->data[$name]); 
  22.  } 
  23. } 
  24. ?> 

__sleep()和__wakeup()

当我们在执行serialize()和unserialize()时,会先调用这两个函数,例如我们在序列化一个对象时,这个对象有一个数据库链接,想要在反序列化中恢复链接状态,则可以通过重构这两个函数来实现链接的恢复,例子如下:

  1. <?php 
  2. class Connection  
  3. { 
  4.  protected $link; 
  5.  private $server, $username, $password, $db; 
  6.  
  7.  public function __construct($server, $username, $password, $db) 
  8.  { 
  9.   $this->server = $server; 
  10.   $this->username = $username; 
  11.   $this->password = $password; 
  12.   $this->db = $db; 
  13.   $this->connect(); 
  14.  } 
  15.  
  16.  private function connect() 
  17.  { 
  18.   $this->link = mysql_connect($this->server, $this->username, $this->password); 
  19.   mysql_select_db($this->db, $this->link); 
  20.  } 
  21.  
  22.  public function __sleep() 
  23.  { 
  24.   return array('server', 'username', 'password', 'db'); 
  25.  } 
  26.  
  27.  public function __wakeup() 
  28.  { 
  29.   $this->connect(); 
  30.  } 
  31. } 
  32. ?> 

__toString()

对象当成字符串时的回应方法,例如使用echo $obj;来输出一个对象

  1. <?php 
  2. // Declare a simple class 
  3. class TestClass 
  4. { 
  5.  public function __toString() { 
  6.   return 'this is a object'; 
  7.  } 
  8. } 
  9.  
  10. $class = new TestClass(); 
  11. echo $class; 
  12. ?> 

这个方法只能返回字符串,而且不可以在这个方法中抛出异常,否则会出现致命错误。

__invoke()

调用函数的方式调用一个对象时的回应方法,如下:

  1. <?php 
  2. class CallableClass  
  3. { 
  4.  function __invoke() { 
  5.   echo 'this is a object'; 
  6.  } 
  7. } 
  8. $obj = new CallableClass; 
  9. var_dump(is_callable($obj)); 
  10. ?> 

__set_state()

调用var_export()导出类时,此静态方法会被调用。

  1. <?php 
  2. class A 
  3. { 
  4.  public $var1; 
  5.  public $var2; 
  6.  
  7.  public static function __set_state ($an_array) { 
  8.   $obj = new A; 
  9.   $obj->var1 = $an_array['var1']; 
  10.   $obj->var2 = $an_array['var2']; 
  11.   return $obj; 
  12.  } 
  13. } 
  14.  
  15. $a = new A; 
  16. $a->var1 = 5; 
  17. $a->var2 = 'foo'; 
  18. var_dump(var_export($a)); 
  19. ?> 

__clone()

当对象复制完成时调用,例如在设计模式详解及PHP实现:单例模式一文中提到的单例模式实现方式,利用这个函数来防止对象被克隆。

  1. <?php  
  2. public class Singleton { 
  3.  private static $_instance = NULL; 
  4.  
  5.  // 私有构造方法  
  6.  private function __construct() {} 
  7.  
  8.  public static function getInstance() { 
  9.   if (is_null(self::$_instance)) { 
  10.    self::$_instance = new Singleton(); 
  11.   } 
  12.   return self::$_instance; 
  13.  } 
  14.  
  15.  // 防止克隆实例 
  16.  public function __clone(){ 
  17.   die('Clone is not allowed.' . E_USER_ERROR); 
  18.  } 
  19. } 
  20. ?> 

魔术常量(Magic constants)

PHP中的常量大部分都是不变的,但是有8个常量会随着他们所在代码位置的变化而变化,这8个常量被称为魔术常量。

__LINE__,文件中的当前行号

__FILE__,文件的完整路径和文件名

__DIR__,文件所在的目录

__FUNCTION__,函数名称

__CLASS__,类的名称

__TRAIT__,Trait的名字

__METHOD__,类的方法名

__NAMESPACE__,当前命名空间的名称

这些魔术常量常常被用于获得当前环境信息或者记录日志。

Tags: php魔术方法 Magic methods

分享到: