PHP构造函数的目的

时间:2010-06-13 15:42:28

标签: php class oop constructor

我正在使用类和对象类结构,但不是在复杂的层面 - 只是类和函数,然后,在一个地方,实例化。

至于__construct__destruct,请告诉我非常简单:构造函数和析构函数的目的是什么

我知道学校层面的理论解释,但我期待现实世界中的某些事情,因为我们必须使用它们。

请提供一个例子。

此致

6 个答案:

答案 0 :(得分:51)

构造函数是在初始化对象(分配内存,复制实例属性等)后执行的函数。其目的是将对象置于有效状态。

通常,处于可用状态的对象需要一些数据。构造函数的目的是强制在实例化时将此数据提供给对象,并禁止没有此类数据的任何实例。

考虑一个封装字符串的简单类,它有一个返回该字符串长度的方法。一种可能的实现方式是:

class StringWrapper {
    private $str;

    public function setInnerString($str) {
        $this->str = (string) $str;
    }

    public function getLength() {
        if ($this->str === null)
            throw new RuntimeException("Invalid state.");
        return strlen($this->str);
    }
}

为了处于有效状态,此功能需要在setInnerString之前调用getLength。通过使用构造函数,可以在调用getLength时强制所有实例处于良好状态:

class StringWrapper {
    private $str;

    public function __construct($str) {
        $this->str = (string) $str;
    }

    public function getLength() {
        return strlen($this->str);
    }
}

您还可以保留setInnerString以允许在实例化后更改字符串。

当一个对象即将从内存中释放时,将调用析构函数。通常,它包含清理代码(例如关闭对象所持有的文件描述符)。它们在PHP中很少见,因为PHP会在脚本执行结束时清除脚本所拥有的所有资源。

答案 1 :(得分:42)

通过示例学习:

class Person {
  public $name;
  public $surname;
  public function __construct($name,$surname){
    $this->name=$name;
    $this->surname=$surname;
  }
}

为什么这有用?因为而不是:

$person = new Person();
$person->name='Christian';
$person->surname='Sciberras';

你可以使用:

$person = new Person('Christian','Sciberras');

代码少,看起来更干净!

注意:正如下面的回复正确陈述,构造函数/析构函数用于各种各样的事情,包括:de /初始化变量(特别是当值是变量时),内存de /分配,不变量(可能是超越)和更清洁的代码。 我还要注意“清洁代码”不仅仅是“糖”,还增强了可读性,可维护性等。

答案 2 :(得分:8)

构造函数在您实例化类的实例时运行。所以如果你有一个班级Person

class Person {

    public $name = 'Bob'; // this is initialization
    public $age;

    public function __construct($name = '') {
        if (!empty($name)) {
            $this->name = $name;
        }
    }

    public function introduce() {
        echo "I'm {$this->name} and I'm {$this->age} years old\n";
    }

    public function __destruct() {
        echo "Bye for now\n";
    }
}

演示:

$person = new Person;
$person->age = 20;
$person->introduce();

// I'm Bob and I'm 20 years old
// Bye for now

我们可以通过构造函数参数覆盖默认值设置:

$person = new Person('Fred');
$person->age = 20;
$person->introduce();

// if there are no other references to $person and 
// unset($person) is called, the script ends 
// or exit() is called __destruct() runs
unset($person);

// I'm Fred and I'm 20 years old
// Bye for now

希望这有助于演示构造函数和析构函数的调用位置,它们对什么有用?

  1. __construct()可以使用资源或更复杂的数据结构来默认类成员。
  2. __destruct()可以释放文件和数据库句柄等资源。
  3. 构造函数通常用于class compositionconstructor injection of required dependencies

答案 3 :(得分:7)

类的构造函数定义从此类实例化对象时发生的情况。类的析构函数定义了销毁对象实例时会发生什么。

请参阅PHP Manual on Constructors and Destructors

  

PHP 5允许开发人员为类声明构造函数方法。具有构造函数方法的类在每个新创建的对象上调用此方法,因此它适用于对象在使用之前可能需要的任何初始化。

  

PHP 5引入了类似于其他面向对象语言(如C ++)的析构函数概念。一旦删除了对特定对象的所有引用,或者在关闭序列中显式销毁对象或以任何顺序,就会调用析构函数方法。

实际上,您使用构造函数将对象置于最小有效状态。这意味着您将传递给构造函数的参数分配给对象属性。如果您的对象使用某些不能直接指定为属性的数据类型,则可以在此处创建它们,例如

class Example
{
    private $database;
    private $storage;

    public function __construct($database)
    {
        $this->database = $database;
        $this->storage = new SplObjectStorage;
    }
}

请注意,为了让您的对象保持可测试性,a constructor should not do any real work

  

在构造函数中工作,例如:创建/初始化协作者,与其他服务通信,以及设置自己状态的逻辑,删除测试所需的接缝,强制子类/模拟继承不需要的行为。构造函数中的太多工作会阻止实例化或改变测试中的协作者。

在上面Example中,$database是合作者。它具有自己的生命周期和目的,可能是一个共享实例。你不会在构造函数中创建它。另一方面,SplObjectStorageExample的组成部分。它具有完全相同的生命周期,不与其他对象共享。因此,可以在ctor中new它。

同样,您使用析构函数来清理对象之后。在大多数情况下,这是不必要的,因为它由PHP自动处理。这就是为什么你会看到比野外的dtors更多的ctors。

答案 4 :(得分:0)

我发现在构造函数之前考虑new关键字时最容易理解:它只是告诉我的变量一个新的数据类型对象将根据哪个构造函数给他调用以及我传入的内容,我可以在到达时定义对象的状态。

如果没有这个新对象,我们将住在null的土地上,然后崩溃!

从C ++的角度来看,析构函数是最明显的,如果你没有析构函数方法删除指向的所有内存,它将在程序退出后继续使用,导致客户端操作系统的泄漏和延迟,直到下次重新启动。< / p>

我确信这里有足够多的好信息,但另一个角度总是对我注意到的有用!

答案 5 :(得分:0)

构造函数是类的函数,当创建类的对象时,该函数会自动执行,我们无需单独调用该构造函数,我们可以将构造函数称为魔术方法,因为在php魔术方法中,双引号是下划线字符