[关闭]
@Chiang 2020-01-07T13:22:23.000000Z 字数 4323 阅读 533

魔术方法

PHP


__construct()

构造函数

  1. __construct([mixed $args [, $... ]]) : void

PHP 5 允行开发者在一个类中定义一个方法作为构造函数。具有构造函数的类会在每次创建新对象时先调用此方法,所以非常适合在使用对象之前做一些初始化工作。

Note: 如果子类中定义了构造函数则不会隐式调用其父类的构造函数。要执行父类的构造函数,需要在子类的构造函数中调用 parent::__construct()。如果子类没有定义构造函数则会如同一个普通的类方法一样从父类继承(假如没有被定义为 private 的话)。
自 PHP 5.3.3 起,在命名空间中,与类名同名的方法不再作为构造函数。这一改变不影响不在命名空间中的类。

__destruct()

析构函数

  1. __destruct ( void ) : void
  • PHP 5 引入了析构函数的概念,这类似于其它面向对象的语言,如 C++。析构函数会在到某个对象的所有引用都被删除或者当对象被显式销毁时执行。
  • 和构造函数一样,父类的析构函数不会被引擎暗中调用。要执行父类的析构函数,必须在子类的析构函数体中显式调用 parent::__destruct()。此外也和构造函数一样,子类如果自己没有定义析构函数则会继承父类的。
  • 析构函数即使在使用 exit() 终止脚本运行时也会被调用。在析构函数中调用 exit() 将会中止其余关闭操作的运行。

Note:
析构函数在脚本关闭时调用,此时所有的 HTTP 头信息已经发出。脚本关闭时的工作目录有可能和在 SAPI(如 apache)中时不同。
Note:
试图在析构函数(在脚本终止时被调用)中抛出一个异常会导致致命错误。

重载

  • PHP所提供的重载(overloading)是指动态地创建类属性和方法。我们是通过魔术方法(magic methods)来实现的。
  • 当调用当前环境下未定义或不可见的类属性或方法时,重载方法会被调用。本节后面将使用不可访问属性(inaccessible properties)和不可访问方法(inaccessible methods)来称呼这些未定义或不可见的类属性或方法。
  • 所有的重载方法都必须被声明为 public。
  • 这些魔术方法的参数都不能通过引用传递。
  • PHP中的重载与其它绝大多数面向对象语言不同。传统的重载是用于提供多个同名的类方法,但各方法的参数类型和个数不同。

属性重载

  • 参数 $name 是指要操作的变量名称。__set() 方法的 $value 参数指定了 $name 变量的值。
  • 属性重载只能在对象中进行。在静态方法中,这些魔术方法将不会被调用。所以这些方法都不能被 声明为 static。从 PHP 5.3.0 起, 将这些魔术方法定义为 static 会产生一个警告。
  • Note:因为 PHP 处理赋值运算的方式,__set() 的返回值将被忽略。类似的, 在下面这样的链式赋值中,__get() 不会被调用:obj->b = 8;
  • Note:在除 isset() 外的其它语言结构中无法使用重载的属性,这意味着当对一个重载的属性使用 empty() 时,重载魔术方法将不会被调用。
    为避开此限制,必须将重载属性赋值到本地变量再使用 empty()。

__get()

读取不可访问属性的值时,__get() 会被调用。

  1. public __get ( string $name ) : mixed

__set()

在给不可访问属性赋值时,__set() 会被调用。

  1. public __set ( string $name , mixed $value ) : void

__isset()

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

  1. public __isset ( string $name ) : bool

__unset()

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

  1. public __unset ( string $name ) : void

方法重载

$name 参数是要调用的方法名称。$arguments 参数是一个枚举数组,包含着要传递给方法 $name 的参数。

__call()

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

  1. public __call ( string $name , array $arguments ) : mixed

__callStatic()

在静态上下文中调用一个不可访问方法时,__callStatic() 会被调用。

  1. public static __callStatic ( string $name , array $arguments ) : mixed

__sleep()

  1. public __sleep ( void ) : array
  • serialize() 函数会检查类中是否存在一个魔术方法 __sleep()。如果存在,该方法会先被调用,然后才执行序列化操作。此功能可以用于清理对象,并返回一个包含对象中所有应被序列化的变量名称的数组。如果该方法未返回任何内容,则 NULL 被序列化,并产生一个 E_NOTICE 级别的错误。
  • __sleep() 不能返回父类的私有成员的名字。这样做会产生一个 E_NOTICE 级别的错误。可以用 Serializable 接口来替代。
  • __sleep() 方法常用于提交未提交的数据,或类似的清理操作。同时,如果有一些很大的对象,但不需要全部保存,这个功能就很好用。

__wakeup()

  1. __wakeup ( void ) : void
  • unserialize() 会检查是否存在一个 __wakeup() 方法。如果存在,则会先调用 __wakeup 方法,预先准备对象需要的资源。
  • __wakeup() 经常用在反序列化操作中,例如重新建立数据库连接,或执行其它初始化操作。
  1. <?php
  2. class Connection
  3. {
  4. protected $link;
  5. private $server, $username, $password, $db;
  6. public function __construct($server, $username, $password, $db)
  7. {
  8. $this->server = $server;
  9. $this->username = $username;
  10. $this->password = $password;
  11. $this->db = $db;
  12. $this->connect();
  13. }
  14. private function connect()
  15. {
  16. $this->link = mysql_connect($this->server, $this->username, $this->password);
  17. mysql_select_db($this->db, $this->link);
  18. }
  19. public function __sleep()
  20. {
  21. return array('server', 'username', 'password', 'db');
  22. }
  23. public function __wakeup()
  24. {
  25. $this->connect();
  26. }
  27. }
  28. ?>

__toString()

  1. public __toString ( void ) : string
  • __toString() 方法用于一个类被当成字符串时应怎样回应。例如 echo $obj; 应该显示些什么。此方法必须返回一个字符串,否则将发出一条 E_RECOVERABLE_ERROR 级别的致命错误。
  • Warning
    不能在 __toString() 方法中抛出异常。这么做会导致致命错误。
  1. <?php
  2. // Declare a simple class
  3. class TestClass
  4. {
  5. public $foo;
  6. public function __construct($foo)
  7. {
  8. $this->foo = $foo;
  9. }
  10. public function __toString() {
  11. return $this->foo;
  12. }
  13. }
  14. $class = new TestClass('Hello');
  15. echo $class;
  16. ?>

__invoke()

  1. __invoke ([ $... ] ) : mixed
  • 当尝试以调用函数的方式调用一个对象时,__invoke() 方法会被自动调用。
  1. <?php
  2. class CallableClass
  3. {
  4. function __invoke($x) {
  5. var_dump($x);
  6. }
  7. }
  8. $obj = new CallableClass;
  9. $obj(5);
  10. var_dump(is_callable($obj));
  11. ?>

__set_state()

  1. static __set_state ( array $properties ) : object
  • 自 PHP 5.1.0 起当调用 var_export() 导出类时,此静态 方法会被调用。
  • 本方法的唯一参数是一个数组,其中包含按 array('property' => value, ...) 格式排列的类属性。

__clone()

对象复制

  1. __clone ( void ) : void
  • 在多数情况下,我们并不需要完全复制一个对象来获得其中属性。但有一个情况下确实需要:如果你有一个 GTK 窗口对象,该对象持有窗口相关的资源。你可能会想复制一个新的窗口,保持所有属性与原来的窗口相同,但必须是一个新的对象(因为如果不是新的对象,那么一个窗口中的改变就会影响到另一个窗口)。还有一种情况:如果对象 A 中保存着对象 B 的引用,当你复制对象 A 时,你想其中使用的对象不再是对象 B 而是 B 的一个副本,那么你必须得到对象 A 的一个副本。
  • 对象复制可以通过 clone 关键字来完成(如果可能,这将调用对象的 __clone() 方法)。对象中的 __clone() 方法不能被直接调用。
  • 当对象被复制后,PHP 5 会对对象的所有属性执行一个浅复制(shallow copy)。所有的引用属性 仍然会是一个指向原来的变量的引用。
  • 当复制完成时,如果定义了 __clone() 方法,则新创建的对象(复制生成的对象)中的 __clone() 方法会被调用,可用于修改属性的值(如果有必要的话)。

__debuginfo()

  1. __debugInfo ( void ) : array

This method is called by var_dump() when dumping an object to get the properties that should be shown. If the method isn't defined on an object, then all public, protected and private properties will be shown.

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注