微信扫一扫打赏支持

php面向对象之构造函数和析构函数

php面向对象之构造函数和析构函数

简介

php面向对象支持两种形式的构造函数和析构函数,一种是和类同名的构造函数(php5.5之前),一类是魔术方法(php5.5之后)。与类名相同的构造函数优先级比魔术方法低。

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__ . "\n";
 7     }
 8 
 9 }
10 
11 class C1 extends P{
12 
13     public function __construct(){
14         echo __CLASS__ . "\n";
15     }
16 
17 }
18 
19 class C2 extends P{
20 
21     public function __construct(){
22         parent::__construct();
23         echo __CLASS__ . "\n";
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\n";
 7     }
 8 
 9     public function __construct(){
10         echo __CLASS__ . "2\n";
11     }
12 
13 }
14 
15 class C2{
16 
17     public function C2(){
18         echo __CLASS__ . "1\n";
19     }
20 
21 }
22 
23 class C3{
24 
25     public function C3(){
26         echo __CLASS__ . "1\n";
27     }
28 
29     public function __construct(){
30         echo __CLASS__ . "2\n";
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__ . "\n";
 9     }   
10 
11 }
12 
13 // Nothing
14 new \N\C();

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

 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__ . "\n";
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) . "\t" . __CLASS__ . "\n";
    }   
}

class C1 extends P{

    function __destruct(){
        echo get_class($this) . "\t" . __CLASS__ . "\n";
    }   

}

class C2 extends P{

    function __destruct(){
        parent::__destruct();
        echo get_class($this) . "\t" . __CLASS__ . "\n";
    }   

}

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
**/

 

代码

 1 <?php
 2 /*php5.5以后用这个魔术常量来写我们的构造函数
 3 function __constrct([参数列表]){
 4 
 5 方法体//通常用来对成员属性进行初始化赋值
 6 
 7 }
 8  * */
 9 class Person{
10     public $userName;
11     public $age;
12 
13     function __construct($userName,$age){
14         echo '我是构造函数,我在new对象的时候会被调用';
15         $this->userName = $userName;
16         $this->age = $age;
17     }
18     function __destruct(){
19         echo '我是析构函数,我在对象被销毁的时候调用';
20     }
21 }
22 // $p = new Person();
23 $p = new Person("Clive", 27);
24 echo '<hr/>';
25 echo $p->age;
26 echo '<hr/>';
27 echo $p->userName;
28 $p = null;
29 
30 /*析构函数
31  * function __destruct() {
32 
33 }
34  *
35  * */

23、构造函数在new对象的时候调用,23行,系统自动调用

28、析构函数在对象已经没有引用的时候调用,比如28行,系统自动调用

 

posted @ 2018-03-11 22:30  范仁义  阅读(267)  评论(0编辑  收藏  举报