PHP构造函数和析构函数


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

PHP的构造函数

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

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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;
}
//... 其他方法
}

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

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

PHP的构造函数重载

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

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

1
2
3
4
5
6
7
8
9
10
11
public function __construct(){
}
 
public function __construct($accountNo){
$this->accountNumber = $accountNo;
}
 
public function __construct($accountNo, $initialAmount){
$this->accountNumber = $accountNo;
$this->totalBalance = $initialAmount;
}

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

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

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

让我们看下面的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
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(),如下所示:

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

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

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
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();


原文链接:https://codingdict.com/