ライフサイクル

プロセスライフサイクル

  • 各プロセスは長いライフサイクルを持つ
  • 各プロセスは独立して実行され、互いに干渉しない
  • 各プロセスはそのライフサイクル内で複数のリクエストを処理できる
  • プロセスはstop reload restartコマンドを受け取ると終了し、本ライフサイクルを終える

ヒント
各プロセスは独立して互いに干渉しないため、各プロセスは自分のリソース、変数、クラスのインスタンスを保持しており、これは各プロセスが自分のデータベース接続を持つこととして現れます。いくつかのシングルトンは各プロセスで一度初期化されるため、複数のプロセスがあれば、多くの初期化が行われます。

リクエストライフサイクル

  • 各リクエストは$requestオブジェクトを生成する
  • $requestオブジェクトはリクエスト処理が完了した後に回収される

コントローライフサイクル

  • 各コントローラは各プロセス内で一度だけインスタンス化され、複数のプロセスで複数回インスタンス化される(コントローラの再利用を除く。詳細はコントローライフサイクルを参照)
  • コントローラのインスタンスは現在のプロセス内の複数のリクエストで共有される(コントローラの再利用を除く)
  • コントローラのライフサイクルはプロセスが終了した後に終わる(コントローラの再利用を除く)

変数ライフサイクルについて

webmanはPHPを基に開発されているため、PHPの変数回収メカニズムに完全に従います。ビジネスロジックで生成された一時変数には、newキーワードで作成されたクラスのインスタンスが含まれ、関数またはメソッドが終了すると自動的に回収され、手動でunsetして解放する必要はありません。つまり、webmanでの開発は従来のフレームワークでの開発と基本的に一致しています。例えば、以下の例では$fooインスタンスはindexメソッドが完了すると自動的に解放されます:

<?php

namespace app\controller;

use app\service\Foo;
use support\Request;

class IndexController
{
    public function index(Request $request)
    {
        $foo = new Foo(); // ここではFooクラスがあると仮定します
        return response($foo->sayHello());
    }
}

特定のクラスのインスタンスを再利用したい場合は、クラスをクラスの静的プロパティまたは長寿命のオブジェクト(例えばコントローラ)のプロパティに保存するか、Containerコンテナのgetメソッドを使用してクラスのインスタンスを初期化することができます。例えば:

<?php

namespace app\controller;

use app\service\Foo;
use support\Container;
use support\Request;

class IndexController
{
    public function index(Request $request)
    {
        $foo = Container::get(Foo::class);
        return response($foo->sayHello());
    }
}

Container::get()メソッドはクラスのインスタンスを作成し保存します。次回、同じパラメータで再度呼び出すと、以前に作成したクラスインスタンスが返されます。

注意
Container::get()は構造パラメータのないインスタンスのみを初期化できます。Container::make()は構造関数パラメータを持つインスタンスを作成できますが、Container::get()とは異なり、Container::make()はインスタンスを再利用しません。つまり、同じパラメータであっても、Container::make()は常に新しいインスタンスを返します。

メモリリークについて

ほとんどのケースにおいて、私たちのビジネスコードでメモリリークが発生することはありません(ごく稀にユーザーからメモリリークの報告があります)。私たちは、長寿命の配列データが無限に拡張しないように注意さえすれば良いです。以下のコードを見てください:

<?php
namespace app\controller;

use support\Request;

class FooController
{
    // 配列プロパティ
    public $data = [];

    public function index(Request $request)
    {
        $this->data[] = time();
        return response('hello index');
    }

    public function hello(Request $request)
    {
        return response('hello webman');
    }
}

コントローラはデフォルトで長寿命です(コントローラの再利用を除く)。同様に、コントローラの$data配列プロパティも長寿命であり、foo/indexリクエストが増えるに従い、$data配列の要素が増え続け、メモリリークを招く可能性があります。

詳細情報はメモリリークを参照してください。