• php魔术方法——构造函数和析构函数


    php有一类很神奇的方法,这些方法是保留方法,通常不会在外部被显式调用,他们使用双下划线(__)开头,他们被称为魔术方法(Magic Methods)。php官方也不建议定义其他双下划线开头的方法。

    这次介绍最常见的魔术方法:构造函数和析构函数。

    1. 构造函数(__construct)

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

    构造函数:拥有构造函数的类会在每次创建新对象时先调用此方法,所以非常适合在使用对象前做一些初始化服务。

    注意:

      1. clone并不会调用构造函数

      2. 如果子类定义了构造函数,则不会隐式调用父类的构造函数

      3. 子类的构造函数允许和父类的构造函数参数不一致

      4. 如果子类没有定义构造函数,php会尝试寻找父类的构造函数

      5. 如果父类没有定义构造函数,使用parent关键字显式调用父类构造函数,会导致致命错误

     1 <?php
     2 
     3 class P{
     4 
     5     public function __construct(){
     6         echo __CLASS__ . "
    ";
     7     }
     8 
     9 }
    10 
    11 class C1 extends P{
    12 
    13     public function __construct(){
    14         echo __CLASS__ . "
    ";
    15     }
    16 
    17 }
    18 
    19 class C2 extends P{
    20 
    21     public function __construct(){
    22         parent::__construct();
    23         echo __CLASS__ . "
    ";
    24     }
    25 
    26 }
    27 
    28 class C3 extends P{
    29 
    30 }
    31 
    32 // P
    33 $ins = new P();
    34 
    35 // Nothing
    36 $ins2 = clone $ins;
    37 
    38 // C1
    39 new C1();
    40 
    41 // P
    42 // C2
    43 new C2();
    44 
    45 // P
    46 new C3();

    除了魔术方法的构造函数,php还支持与类名相同的构造函数,不过优先级比魔术方法低:

     1 <?php
     2 
     3 class C1{
     4 
     5     public function C1(){
     6         echo __CLASS__ . "1
    ";
     7     }
     8 
     9     public function __construct(){
    10         echo __CLASS__ . "2
    ";
    11     }
    12 
    13 }
    14 
    15 class C2{
    16 
    17     public function C2(){
    18         echo __CLASS__ . "1
    ";
    19     }
    20 
    21 }
    22 
    23 class C3{
    24 
    25     public function C3(){
    26         echo __CLASS__ . "1
    ";
    27     }
    28 
    29     public function __construct(){
    30         echo __CLASS__ . "2
    ";
    31         $this->C3();
    32     }
    33 
    34 }
    35 
    36 // C12
    37 new C1();
    38 
    39 // C21
    40 new C2();
    41 
    42 // C32
    43 // C31
    44 new C3();

    php5.3.3之后,在命名空间之内使用与类名同名的方法,不再作为构造函数,命名空间之外不变:

     1 <?php
     2 
     3 namespace N;
     4 
     5 class C{
     6 
     7     public function C(){
     8         echo __CLASS__ . "
    ";
     9     }   
    10 
    11 }
    12 
    13 // Nothing
    14 new NC();

    构造函数可以用全部三个访问控制修饰符,如单例模式:

     1 <?php
     2 
     3 class Single{
     4 
     5     public static function getInstance(){
     6         static $ins = null;
     7         if(empty($ins)){
     8             $ins = new self();
     9         }   
    10         return $ins;
    11     }   
    12 
    13     private function __construct(){
    14         echo __CLASS__ . "
    ";
    15     }   
    16 
    17 }
    18 
    19 // Single
    20 Single::getInstance();

    2. 析构函数(__destruct)

    void __destruct ( void )

    析构函数:析构函数会在某个对象的引用被全部删除或对象被显示销毁时执行。

    注意:

      1. 同构造函数类似,父类的析构函数并不会被引擎暗中调用,必须显式调用parent::__destruct

      2. exit和die并不能阻止析构函数的执行

      3. 致命错误会阻止析构函数的执行

      4. 在析构函数中调用exit,可以阻止其他未执行的析构函数的执行

      5. 如果父类没有定义析构函数,使用parent关键字显式调用父类析构函数,会导致致命错误

    <?php
    
    class P{
    
        function __destruct(){
            echo get_class($this) . "	" . __CLASS__ . "
    ";
        }   
    }
    
    class C1 extends P{
    
        function __destruct(){
            echo get_class($this) . "	" . __CLASS__ . "
    ";
        }   
    
    }
    
    class C2 extends P{
    
        function __destruct(){
            parent::__destruct();
            echo get_class($this) . "	" . __CLASS__ . "
    ";
        }   
    
    }
    
    class C3 extends P{
    
    }
    
    $insP = new P();
    $ins1 = new C1();
    $ins2 = new C2();
    $ins3 = new C3();
    
    /**
    输出:
    C3    P
    C2    P
    C2    C2
    C1    C1
    P    P
    **/
  • 相关阅读:
    flask 跨域问题
    pip 命令参数说明
    关于ASP.NET动态加载控件的几点实用总结
    记录代码运行耗时的写法
    DevExpress AspxGridView数据绑定
    发现一个Membership的bug
    asp.net页面中文件下载的2种方式
    【部分转】innerText 跟 innerHTML区别
    gridview 的添加删除等技巧 全部按名称取值
    关于Linq to DataTable not in的写法
  • 原文地址:https://www.cnblogs.com/365star/p/5231225.html
Copyright © 2020-2023  润新知