# 构造函数和析构函数

PHP 允许开发者在一个类中定义一个方法作为构造函数。具有构造函数的类会在每次创建新对象时先调用此方法，所以非常适合在使用对象之前做一些初始化工作。

```php
<?php

class Foo
{
    /**
     * Just a test property.
     *
     * @var string
     */
    public string $property;

    /**
     * Initialize the value of the property.
     *
     * @param  void
     * @return void
     */
    public function __construct()
    {
        $this->property = 'foo';
    }
}

$foo = new Foo();
var_dump($foo->property); // string(3) "foo"

```

如果子类中定义了构造函数则不会隐式调用其父类的构造函数。要执行父类的构造函数，需要在子类的构造函数中调用 `parent::__construct()` 。如果子类没有定义构造函数则会如同一个普通的类方法一样从父类继承（假如没有被定义为 `private` 的话）。

```php
<?php

class Foo
{
    /**
     * Just a test property.
     *
     * @var string
     */
    public string $property;

    /**
     * Initialize the value of the property.
     *
     * @param  void
     * @return void
     */
    public function __construct()
    {
        $this->property = 'foo';
    }
}

class Bar
{
    /**
     * Override the parent constructor.
     *
     * @param  void
     * @return void
     */
    public function __construct()
    {
        $this->property = 'bar';
    }
}

class Baz extends Foo
{
    /**
     * Call the parent constructor.
     *
     * @param  void
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }
}

class Qux extends Foo
{
    //
}

$foo = new Foo();
var_dump($foo->property); // string(3) "foo"

$bar = new Bar();
var_dump($bar->property); // string(3) "bar"

$baz = new Baz();
var_dump($baz->property); // string(3) "foo"

$qux = new Qux();
var_dump($qux->property); // string(3) "foo"

```

PHP 引入了析构函数的概念，析构函数会在到某个对象的所有引用都被删除或者当对象被显式销毁时执行。

```php
<?php

class Foo
{
    /**
     * Just a test destructor.
     *
     * @param  void
     * @return void
     */
    public function __destruct()
    {
        var_dump('foo');
    }
}

$foo = new Foo();
unset($foo);
// string(3) "foo"

```

和构造函数一样，父类的析构函数不会被引擎暗中调用。要执行父类的析构函数，必须在子类的析构函数体中显式调用 `parent::__destruct()` 。此外也和构造函数一样，子类如果自己没有定义析构函数则会继承父类的。析构函数即使在使用 `exit()` 终止脚本运行时也会被调用。在析构函数中调用 `exit()` 将会中止其余关闭操作的运行。

```php
<?php

class Foo
{
    /**
     * Just a test destructor.
     *
     * @param  void
     * @return void
     */
    public function __destruct()
    {
        var_dump('foo');
    }
}

class Bar extends Foo
{
    /**
     * Override the parent destructor.
     *
     * @param  void
     * @return void
     */
    public function __destruct()
    {
        var_dump('bar');
    }
}

class Baz extends Foo
{
    /**
     * Call the parent destructor.
     *
     * @param  void
     * @return void
     */
    public function __destruct()
    {
        parent::__destruct();
    }
}

class Qux extends Foo
{
    //
}

$foo = new Foo();
unset($foo);
$bar = new Bar();
unset($bar);
$baz = new Baz();
unset($baz);
$qux = new Qux();
unset($qux);
// string(3) "foo"
// string(3) "bar"
// string(3) "foo"
// string(3) "foo"

```

