77751


あるPHPの入門書にデストラクタについての解説があります。

> ＊デストラクタ  
>  コンストラクタとは反対に、オブジェクトが破棄されるタイミングで実行されるのがデストラクタです。名前は __destructに固定されている。  
>  デストラクタには、クラスの中で使用したリソースを破棄するなど、主に終了するときの処理を記述するのが一般的です。

以下のような記述をしました。(person.php)

[code]

    <?php
    
    class Person{
    
      public $lastName;
      public $firstName;
    
    　public function __construct($lastName, $firstName){
        $this->firstName = $firstName;
        $this->lastName = $lastName;
      }
    
      public function show(){
        print "<p>私の名前は {$this->lastName} {$this->firstName}です。</p>";
        }
    
      public function __destruct(){
        print "<p>インスタンスが破棄されました。<p>";
      　}
      }
      ?>
    
[/code]

上の記述をインスタンス化する記述です。(instancne.php)

[code]

    <?php
    require_once('person.php');
    
    $p = new Person('田中', '幸太郎');
    $p->show();
    ?>
    
[/code]

＜表示結果＞

[code]

    私の名前は 田中 幸太郎です。
    
    インスタンスが破棄されました。
    
[/code]

となります。試しにもうひとつインスタンスを追加します。

[code]

    <?php
        require_once('person.php');
        
        $p = new Person('田中', '幸太郎');
        $p->show();
        $p1 = new Person('鈴木', '京子');
        $p1->show();
        ?>
    
[/code]

＜表示結果＞

[code]

    私の名前は 田中 幸太郎です。
    
    私の名前は 鈴木 京子です。
    
    インスタンスが破棄されました。
    
    インスタンスが破棄されました。
    
[/code]

説明にある、  
「オブジェクトが破棄されるタイミングで実行されるのがデストラクタです。」  
「デストラクタには、クラスの中で使用したリソースを破棄するなど、主に終了するときの処理を記述するのが一般的です。」

これらの意味がわかりません。

コンストラクタの  
「new 演算子によってインスタンス化されるタイミングで実行される」  
「プロパティの初期化」  
などの意味は理解できているつもりです。

デストラクタを使うと「オブジェクトが破棄される」、「クラスの中で使用したリソースを破棄する」とありますが、『一度インスタンスを作るとクラス内のリソースが破棄されるのかな？』と思い、試しにもう一つインスタンスを作成しました。上記の通り問題なく使えています。  
膨大な記述になると、クラス、この場合は 「class Person」」は再利用出来なくすると言った意味になるのでしょうか？

他の教材やネットで検索してみたりしたのですが、イメージがつかめません。  
以下のPHP公式のサイトから考えてみると、クラス内で参照できるものがなければ、コールされるという風に解釈できるかもしれませんが、意味がわかりません。

デストラクタ(__destruct)はコンストラクタ(__construct)の反対というように記述されているものもありますが余計に意味が分かりません。

初学者にもわかるようにデストラクタについて教えてもらえないでしょうか？  
またどういうケースで利用するのかもよく分かりません。  
そのあたりも併せて教えて下さい。  
宜しくお願いいたいます。

**参考:**

[デストラクタ | PHP Manual](https://www.php.net/manual/ja/language.oop5.decon.php)

>
[code]

>     __destruct(): void
>  
[/code]

>
> PHP には、C++ のような他のオブジェクト指向言語に似たデストラクタの概念があります。 デストラクタメソッドは、
> 特定のオブジェクトを参照するリファレンスがひとつもなくなったときにコールされます。 あるいは、スクリプトの終了時にも順不同でコールされます。


CC BY-SA 4.0
2021-06-23T06:38:08.013
77731
2021-06-24T00:54:19.370
2021-06-23T08:33:53.350
3060
42150
question
php
デストラクタ __destruct はどのような時に使うのですか？


ここで示しているリソースとは、外部と連携して利用しているリンクや[リソース](https://www.php.net/manual/ja/language.types.resource.php)を指します。

一番有名なところですとMySQLなどのDBのリソースでしょう。

DBを例にとると  
クラスの中でDBとコネクションを実施してリソースを確保して、処理を行います。  
もしリソースを明示的に破棄しないと、OS側ではつながったままです。  
OSのコネクション数にも限界がありますし余分にコストをかける必要性はないので一旦破棄しようとなったときにデストラクタで処理すると一括で処理できてわかりやすくなります。

他にもいろいろな外部と連携する用の[リソース](https://www.php.net/manual/ja/resource.php)が存在します。  
そもそも破棄するのも必要がないものもあったりしますが、一般的にはつないで必要がなくなったら切っておくが理想的なプログラムでしょう


CC BY-SA 4.0
2021-06-23T07:08:53.683
77734
2021-06-23T07:08:53.683
22665
77731
answer


>
> 他の教材やネットで検索してみたりしたのですが、イメージがつかめません。以下のPHP公式のサイトから考えてみると、クラス内で参照できるものがなければ、コールされるという風に解釈できるかもしれませんが、意味がわかりません。

#### 原文(英語)

[PHP: Constructors and
Destructors](https://www.php.net/manual/en/language.oop5.decon.php#language.oop5.decon.destructor)

> **Destructor**
>
> PHP possesses a destructor concept similar to that of other object-oriented
> languages, such as C++. The destructor method will be called as soon as
> there are no other references to a particular object, or in any order during
> the shutdown sequence.

例えば関数内のローカル変数を考えてみると良いかもしれません。以下にサンプルコードを示しますが、`NewPerson()` 関数の実行が完了した時点で
destructor が実行されている事が判ります。

[code]

    <?php
    
    require_once('person.php');
    
    function NewPerson() {
      $p = new Person('田中', '幸太郎');
      $p->show();
    }
    
    NewPerson();
    echo "<p>Done.<p>";
    
    $p = new Person('山田', '太郎');
    $p->show();
    
    echo "<p>Exit.<p>";
    
[/code]

#### 実行結果

[code]

    私の名前は 田中 幸太郎です。
    
    インスタンスが破棄されました。
    
    Done.
    
    私の名前は 山田 太郎です。
    
    Exit.
    
    インスタンスが破棄されました。
    
[/code]


CC BY-SA 4.0
2021-06-23T11:00:12.597
77742
2021-06-23T11:00:12.597
77731
answer


質問本文を拝見するに「インスタンスに所属するもの」「クラスに所属するもの」「クラス自体」の区別がついていないような気がします。提示例 `Person`
において `firstName` と `lastName` はインスタンスに所属するものです。なので **インスタンス`p1` が破棄**されるとき
`p1->firstName` も一緒に破棄されるわけです。 `p1` の破棄（デストラクト）の際にクラス `Person`
が破棄されることはありません。実際 @metropolis 氏のサンプルでそのように挙動しています。

提示例は `php` 自体が提供している文字列のみを利用しているので破棄の際に必要な処理は `php` 自体が勝手に行っているというか `php`
だけで完結しているというか。だから「デストラクタ」で特別な処理を行う必要が無いので余計に必要性がわからないというか。オイラ `php`
はメインに使っている言語でない関係でサンプルを出せるとしたら [c++](/questions/tagged/c%2b%2b "'c++'
のタグが付いた質問を表示") (それも better C としてのサンプル)

[code]

    struct filetest_type {
        FILE* f;
        filetest_type() : f(NULL) { }
        ~filetest_type() {
            if (f!=NULL) fclose(f);
        }
        void open(const char* fn) {
            f=fopen(fn, "r");
        }
    };
    
[/code]


CC BY-SA 4.0
2021-06-24T00:54:19.370
77751
2021-06-24T00:54:19.370
8589
77731
answer