Lifecycle
Process Lifecycle
- Each process has a long lifecycle.
- Each process runs independently, without interference.
- Each process can handle multiple requests within its lifecycle.
- When a process receives the
stop
,reload
, orrestart
command, it will exit and end its current lifecycle.
Tip
Each process runs independently without interference, which means each process maintains its own resources, variables, class instances, etc. This is reflected in each process having its own database connection, and some singletons being initialized once for each process, leading to multiple initializations across processes.
Request Lifecycle
- Each request generates a
$request
object. - The
$request
object is recycled after the request is processed.
Controller Lifecycle
- Each controller is instantiated only once per process, but multiple instantiations are possible across processes (unless controller reusing is disabled, see Controller Lifecycle).
- Controller instances are shared among multiple requests within the current process (unless controller reusing is disabled).
- The controller's lifecycle ends when the process exits (unless controller reusing is disabled).
Variable Lifecycle
webman is developed based on PHP, so it fully complies with PHP's variable recycling mechanism. Temporary variables created in business logic, including instances of classes created with the new
keyword, are automatically recycled after a function or method ends, without the need for manual unset
releases. This means that the development experience with webman is essentially the same as with traditional frameworks. For example, in the following example, the $foo
instance will be automatically released when the index
method finishes executing:
<?php
namespace app\controller;
use app\service\Foo;
use support\Request;
class IndexController
{
public function index(Request $request)
{
$foo = new Foo(); // Assuming there is a Foo class here
return response($foo->sayHello());
}
}
If you want an instance of a class to be reused, you can save the class to the class's static property or to a property of a long-lived object (such as a controller). You can also use the Container
container's get
method to initialize the class instance, for example:
<?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());
}
}
The Container::get()
method is used to create and save class instances, so that the same parameters used in a subsequent call will return the previously created class instance.
Note
Container::get()
can only initialize instances without constructor parameters.Container::make()
can create instances with constructor parameters, but unlikeContainer::get()
,Container::make()
does not reuse instances, meaning that it always returns a new instance, even with the same parameters.
About Memory Leaks
In most cases, our business code does not cause memory leaks (very few users have reported memory leaks). We just need to be mindful not to infinitely expand long-lived array data. Consider the following code:
<?php
namespace app\controller;
use support\Request;
class FooController
{
// Array property
public $data = [];
public function index(Request $request)
{
$this->data[] = time();
return response('hello index');
}
public function hello(Request $request)
{
return response('hello webman');
}
}
By default, the controller has a long lifecycle (unless controller reusing is disabled), and similarly, the $data
array property of the controller also has a long lifecycle. As the foo/index
request continues to add elements to the $data
array, it leads to a memory leak.
For more information, please refer to Memory Leaks.