PHP构造函数和析构函数

时间:2018-11-15 15:13:04  来源:igfitidea点击:

在本教程中,我们将学习如何使用构造函数初始化对象的属性,并使用析构函数从内存中释放对象之前清理资源。

PHP的构造函数

当你创建一个新对象时就初始化它的属性是很有用的,例如,对于银行账户对象,你可以设置它的初始余额为一个特定的金额。PHP提供了一个特殊的方法来帮助初始化对象的属性,称为构造函数。

要将构造函数添加到类中,只需添加一个名称为_construct()的特殊方法。每当创建一个新对象时,PHP都会搜索这个方法并自动调用它。

下面的例子向BankAccount类添加了一个构造函数,用于初始化帐号和初始金额:

class BankAccount{
    /**
    * 银行账户号码
    * @var string bank account number
    */
    private $accountNumber;
    /**
    * 总余额
    * @var float total balance
    */
    private $totalBalance;
    
    /**
    * 初始化银行账户的号码和初始金额
    * 
    * @param string $accountNo
    * @param float  $initialAmount
    */
    public function __construct($accountNo, $initialAmount){
        $this->accountNumber = $accountNo;
        $this->totalBalance = $initialAmount;
    }
    //... 其他方法
}

现在,您可以使用帐号和初始金额创建一个新的银行帐户对象,如下所示:

// 创建一个新的银行帐户对象
$account = new BankAccount('12345678',1000);

PHP的构造函数重载

构造函数重载允许您创建多个具有相同名称但参数不同的构造函数。
构造函数重载使您能够以各种方式初始化对象的属性。

下面的例子演示了构造函数重载的思想:

public function __construct(){ 
}
 
public function __construct($accountNo){
    $this->accountNumber = $accountNo;
}
 
public function __construct($accountNo, $initialAmount){
    $this->accountNumber = $accountNo;
    $this->totalBalance = $initialAmount;
}

我们创建了三个构造函数:

  • 第一个是空的,不做任何事
  • 第二个只初始化帐号。
  • 第三个同时初始化账号和初始金额。

不过PHP还不支持构造函数重载。幸运的是,您可以通过使用几个PHP函数来实现相同的构造函数重载效果。

让我们看下面的例子:

class BankAccount{
 /**
 * 银行账户号码
 * @var string bank account number
 */
 private $accountNumber;
 /**
 * 总余额
 * @var float total balance
 */
 private $totalBalance;
 
 /**
 * 初始化银行账户的号码和初始金额
 * @param string $accountNo
 * @param float  $initialAmount
 */
 
 public function __construct(){
    $args = func_get_args();
    $num = func_num_args();
    if(method_exists($this,$f = 'init_' . $num)) {
        call_user_func_array(array($this,$f),$args);
    }
 }
 
 public function init_1($accountNo){
    $this->accountNumber = $accountNo;
 }
 
 public function init_2($accountNo,$initialAmount){
    $this->accountNumber = $accountNo;
    $this->totalBalance = $initialAmount; 
 }
 //... 其他方法
}
 
$a1 = new BankAccount('123456', 100);
var_dump($a1);
 
$a2 = new BankAccount('223456');
var_dump($a2);

首先我们使用func_get_args()函数获得构造函数的参数,还使用func_num_args()函数获得参数的数量。
然后我们使用method_exists()函数根据构造函数的参数数量来检查init_1()和init_2()方法是否存在。
如果对应的方法存在,则使用call_user_func_array()函数来调用它。

PHP析构函数

PHP析构函数允许您在PHP从内存中释放对象之前清理资源。
例如,您可以在构造函数中创建一个文件句柄,然后在析构函数中关闭它。

要将析构函数添加到类中,只需简单地添加一个特殊的方法__destruct(),如下所示:

public function __destruct(){
    // 清理资源的代码
}

关于析构函数,有一些点需要注意:

  • 与构造函数不同,析构函数不能接受任何参数。
  • 在删除对象之前,对象的析构函数将被调用。这通常发生在这些情况下:当对象没有被引用或者执行了exit()函数停止脚本时。

下面的简单FileUtil类演示如何使用析构函数关闭文件句柄。

class FileUtil{
 
 private $handle;
 private $filename;
 
 /**
 * 使用filename和mode初始化FileUtil
 * @param string $filename
 * @param string $mode
 */
 public function __construct($filename,$mode){
 $this->filename = $filename;
 $this->handle = fopen($filename, $mode);
 }
 
 /**
 * 关闭文件句柄
 */
 public function __destruct(){
 if($this->handle){
 fclose($this->handle);
 }
 }
 /**
 * 显示文件内容
 */
 public function display(){
 echo fread($this->handle, filesize($this->filename));
 }
}
 
$fu = new FileUtil('./test.txt', 'r');
$fu->display();