PHP 构造函数的目的

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3032808/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 08:29:01  来源:igfitidea点击:

Purpose of PHP constructors

phpclassoopconstructor

提问by Bharanikumar

I am working with classes and object class structure, but not at a complex level – just classes and functions, then, in one place, instantiation.

我正在处理类和对象类结构,但不是在一个复杂的级别——只是类和函数,然后,在一个地方,实例化。

As to __constructand __destruct, please tell me very simply: what is the purpose of constructors and destructors?

至于__constructand __destruct,请简单地告诉我:构造函数和析构函数的目的是什么?

I know the school level theoretical explanation, but i am expecting something like in real world, as in which situations we have to use them.

我知道学校水平的理论解释,但我期待在现实世界中的东西,就像我们必须在哪些情况下使用它们一样。

Provide also an example, please.

还请举个例子。

Regards

问候

回答by Artefacto

A constructor is a function that is executed after the object has been initialized (its memory allocated, instance properties copied etc.). Its purpose is to put the object in a valid state.

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

Frequently, an object, to be in an usable state, requires some data. The purpose of the constructor is to force this data to be given to the object at instantiation time and disallow any instances without such data.

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

Consider a simple class that encapsulates a string and has a method that returns the length of this string. One possible implementation would be:

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

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);
    }
}

In order to be in a valid state, this function requires setInnerStringto be called before getLength. By using a constructor, you can force all the instances to be in a good state when getLengthis called:

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

class StringWrapper {
    private $str;

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

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

You could also keep the setInnerStringto allow the string to be changed after instantiation.

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

A destructor is called when an object is about to be freed from memory. Typically, it contains cleanup code (e.g. closing of file descriptors the object is holding). They are rare in PHP because PHP cleans all the resources held by the script when the script execution ends.

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

回答by Christian

Learn by example:

通过例子学习:

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

Why is this helpful? Because instead of:

为什么这有帮助?因为而不是:

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

you can use:

您可以使用:

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

Which is less code and looks cleaner!

哪个代码更少,看起来更干净!

Note: As the replies below correctly state, constructors/destructors are used for a wide variety of things, including: de/initialization of variables (especially when the the value is variable), memory de/allocation, invariants (could be surpassed) and cleaner code. I'd also like to note that "cleaner code" is not just "sugar" but enhances readability, maintainability etc.

注意:正如下面的回复正确指出的,构造函数/析构函数用于各种各样的事情,包括:变量的解除/初始化(尤其是当值是可变的)、内存解除/分配、不变量(可能被超越)和更干净的代码。我还想指出,“更干净的代码”不仅仅是“糖”,而是增强了可读性、可维护性等。

回答by Greg K

The constructor is run at the time you instantiate an instance of your class. So if you have a class Person:

构造函数在您实例化类的实例时运行。所以如果你有一个类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";
    }
}

To demonstrate:

展示:

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

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

We can override the default value set with initialization via the constructor argument:

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

$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

Hopefully that helps demonstrate where the constructor and destructor are called, what are they useful for?

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

  1. __construct()can default class members with resources or more complex data structures.
  2. __destruct()can free resources like file and database handles.
  3. The constructor is often used for class compositionor constructor injection of required dependencies.
  1. __construct()可以使用资源或更复杂的数据结构来默认类成员。
  2. __destruct()可以释放文件和数据库句柄等资源。
  3. 构造函数通常用于类组合构造函数注入所需的依赖项

回答by Gordon

The constructor of a class defines what happens when you instantiate an object from this class. The destructor of a class defines what happens when you destroy the object instance.

类的构造函数定义了当你从这个类实例化一个对象时会发生什么。类的析构函数定义了销毁对象实例时会发生什么。

See the PHP Manual on Constructors and Destructors:

请参阅有关构造函数和析构函数PHP 手册

PHP 5 allows developers to declare constructor methods for classes. Classes which have a constructor method call this method on each newly-created object, so it is suitable for any initialization that the object may need before it is used.

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

and

PHP 5 introduces a destructor concept similar to that of other object-oriented languages, such as C++. The destructor method will be called as soon as all references to a particular object are removed or when the object is explicitly destroyed or in any order in shutdown sequence.

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

In practise, you use the Constructor to put the object into a minimum valid state. That means you assign arguments passed to the constructor to the object properties. If your object uses some sort of data types that cannot be assigned directly as property, you create them here, e.g.

在实践中,您使用构造函数将对象置于最低有效状态。这意味着您将传递给构造函数的参数分配给对象属性。如果您的对象使用某种无法直接分配为属性的数据类型,您可以在此处创建它们,例如

class Example
{
    private $database;
    private $storage;

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

Note that in order to keep your objects testable, a constructor should not do any real work:

请注意,为了保持您的对象可测试,构造函数不应做任何实际工作

Work in the constructor such as: creating/initializing collaborators, communicating with other services, and logic to set up its own state removes seams needed for testing, forcing subclasses/mocks to inherit unwanted behavior. Too much work in the constructor prevents instantiation or altering collaborators in the test.

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

In the above Example, the $databaseis a collaborator. It has a lifecycle and purpose of it's own and may be a shared instance. You would not create this inside the constructor. On the other hand, the SplObjectStorageis an integral part of Example. It has the very same lifecycle and is not shared with other objects. Thus, it is okay to newit in the ctor.

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

Likewise, you use the destructor to clean up after your object. In most cases, this is unneeded because it is handled automatically by PHP. This is why you will see much more ctors than dtors in the wild.

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

回答by Jake Kalstad

I've found it was easiest to grasp when I thought about the newkeyword before the constructor: it simply tells my variable a new object of its data type would be give to him, based on which constructor I call and what I pass into it, I can define to state of the object on arrival.

我发现当我new在构造函数之前考虑关键字时最容易掌握:它只是告诉我的变量一个数据类型的新对象将提供给他,基于我调用的构造函数和我传递给它的内容,我可以定义到达时对象的状态。

Without the new object, we would be living in the land of null, and crashes!

如果没有新对象,我们将生活在null,并崩溃的土地上!

The Destructor is most obvious from a C++ stand point, where if you dont have a destructor method delete all the memory pointed to, it will stay used after the program exits causing leaks and lag on the clients OS untill next reboot.

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

I'm sure there's more than enough good information here, but another angle is always helpful from what I've noticed!

我相信这里有足够多的好信息,但从我注意到的角度来看,另一个角度总是有帮助的!

回答by Shriyash Deshmukh

constructor is function of class which is executed automatically when object of class is created we need not to call that constructor separately we can say constructor as magic method because in php magic method begin with double underscore characters

构造函数是类的函数,在创建类的对象时自动执行我们不需要单独调用该构造函数我们可以说构造函数为魔术方法,因为在 php 魔术方法中以双下划线字符开头