ライフサイクル
プロセスライフサイクル
- 各プロセスは長いライフサイクルを持つ
- 各プロセスは独立して実行され、互いに干渉しない
- 各プロセスはそのライフサイクル内で複数のリクエストを処理できる
- プロセスは
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
配列の要素が増え続け、メモリリークを招く可能性があります。
詳細情報はメモリリークを参照してください。