构造函数

注意

PHP 3 和 PHP4 的构造函数有所不同。PHP 4 的语义更可取。

构造函数是类中的一个特殊函数,当使用 new 操作符创建一个类的实例时,构造函数将会自动调用。PHP 3 中,当函数与类同名时,这个函数将成为构造函数。PHP 4 中,在类里定义的函数与类同名时,这个函数将成为一个构造函数 - 区别很微妙,但非常关键(见下文)。

<?php
// PHP 3 和 PHP 4 中都能用
class Auto_Cart extends Cart
{
    function
Auto_Cart()
    {
        
$this->add_item ("10", 1);
    }
}
?>

上文定义了一个 Auto_Cart 类,即 Cart 类加上一个构造函数,当每次使用“new”创建一个新的 Auto_Cart 类实例时,构造函数将自动调用并将一件商品的数目初始化为“10”。构造函数可以使用参数,而且这些参数可以是可选的,它们可以使构造函数更加有用。为了依然可以不带参数地使用类,所有构造函数的参数应该提供默认值,使其可选。

<?php
// PHP 3 和 PHP 4 中都能用
class Constructor_Cart extends Cart
{
    function
Constructor_Cart($item = "10", $num = 1)
    {
        
$this->add_item ($item, $num);
    }
}

// 买些同样无聊的老货

$default_cart = new Constructor_Cart;

// 买些新东西...

$different_cart = new Constructor_Cart("20", 17);
?>

你也可以使用 @ 操作符来消除发生在构造函数中的错误。例如 @new

注意

PHP 3 中派生类和构造函数有许多限制。仔细阅读下列范例以理解这些限制。

<?php
class A
{
    function
A()
    {
      echo
"I am the constructor of A.<br>\n";
    }
}

class
B extends A
{
    function
C()
    {
        echo
"I am a regular function.<br>\n";
    }
}

// PHP 3 中没有构造函数被调用
$b = new B;
?>

PHP 3 中,在上面的示例中将不会有构造函数被调用。PHP 3 的规则是:“构造函数是与类同名的函数”。这里,类的名字是 B,但是类 B 中没有函数 B()。什么也不会发生。

PHP 4 修正了这个问题,并介绍了另外的新规则:如果一个类没有构造函数,如果父类有构造函数的话,父类的构造函数将会被调用。PHP 4 中,上面的例子将会输出“I am the constructor of A.<br>”。

<?php
class A
{
    function
A()
    {
        echo
"I am the constructor of A.<br>\n";
    }

    function
B()
    {
        echo
"I am a regular function named B in class A.<br>\n";
        echo
"I am not a constructor in A.<br>\n";
    }
}

class
B extends A
{
    function
C()
    {
        echo
"I am a regular function.<br>\n";
    }
}

// 调用 B() 作为构造函数
$b = new B;
?>

如果是 PHP 3,类 A 中的函数 B() 将立即成为类 B 中的构造函数,虽然并不是有意如此。PHP 3 中的规则是:“构造函数是与类同名的函数”。PHP 3 并不关心函数是不是在类 B 中定义的,或者是否已经被继承。

PHP 4 修改了规则:“构造函数与定义其自身的类同名”。因而在 PHP 4 中,类 B 将不会有属于自身的构造函数,并且父类的构造函数将会被调用,输出“I am the constructor of A.<br>”。

【译者注】这里似乎有问题,实际输出的结果,并不象这里说的那样。实际输出的内容是“I am a regular function named B in class A......”,输出的是 B() 的内容。也就是说,例子中的注释“This will call B() as a constructor”是正确的。如果从 A 类中移除函数 B(),那么将输出 A() 的内容。

注意

不管是 PHP 3 还是 PHP 4 都不会从派生类的构造函数中自动调用基类的构造函数。恰当地逐次调用上一级的构造函数是用户的责任。

注: PHP 3 或者 PHP 4 中都没有析构函数。你可以使用 register_shutdown_function() 函数来模拟多数析构函数的效果。

析构函数是一种当对象被销毁时,无论使用了 unset() 或者简单的脱离范围,都会被自动调用的函数。但 PHP 中没有析构函数。