注意事项
单例问题
传统FPM下,单例模式的对象的生命周期仅在每次请求中,请求开始=>实例化单例=>请求结束后=>单例对象资源回收。
Swoole Server下,所有单例对象会常驻于内存,这个时候单例对象的生命周期与FPM不同,请求开始=>实例化单例=>请求结束=>单例对象依旧保留,需要开发者自己维护单例的状态。
如果你的项目中使用到了Session、Authentication、JWT,请根据情况解除
laravels.php
中cleaners
的注释。常见的解决方案:
写一个
XxxCleaner
类来清理单例对象状态,此类需实现接口Hhxsv5\LaravelS\Illuminate\Cleaners\CleanerInterface
,然后注册到laravels.php
的cleaners
中。用一个
中间件
来重置
单例对象的状态。如果是以
ServiceProvider
注册的单例对象,可添加该ServiceProvider
到laravels.php
的register_providers
中,这样每次请求会重新注册该ServiceProvider
,重新实例化单例对象,参考。
应通过
Illuminate\Http\Request
对象来获取请求信息,$_ENV是可读取的,$_SERVER是部分可读的,不能使用
$_GET、$_POST、$_FILES、$_COOKIE、$_REQUEST、$_SESSION、$GLOBALS。
- public function form(\Illuminate\Http\Request $request)
- {
- $name = $request->input('name');
- $all = $request->all();
- $sessionId = $request->cookie('sessionId');
- $photo = $request->file('photo');
- // 调用getContent()来获取原始的POST body,而不能用file_get_contents('php://input')
- $rawContent = $request->getContent();
- //...
- }
- 推荐通过返回
Illuminate\Http\Response
对象来响应请求,兼容echo、vardump()、print_r(),不能使用
函数像 dd()、exit()、die()、header()、setcookie()、http_response_code()。
- public function json()
- {
- return response()->json(['time' => time()])->header('header1', 'value1')->withCookie('c1', 'v1');
- }
各种
单例的连接
将被常驻内存,建议开启持久连接
。数据库连接,连接断开后会自动重连
- // config/database.php
- 'connections' => [
- 'my_conn' => [
- 'driver' => 'mysql',
- 'host' => env('DB_MY_CONN_HOST', 'localhost'),
- 'port' => env('DB_MY_CONN_PORT', 3306),
- 'database' => env('DB_MY_CONN_DATABASE', 'forge'),
- 'username' => env('DB_MY_CONN_USERNAME', 'forge'),
- 'password' => env('DB_MY_CONN_PASSWORD', ''),
- 'charset' => 'utf8mb4',
- 'collation' => 'utf8mb4_unicode_ci',
- 'prefix' => '',
- 'strict' => false,
- 'options' => [
- // 开启持久连接
- \PDO::ATTR_PERSISTENT => true,
- ],
- ],
- //...
- ],
- //...
- Redis连接,连接断开后
不会立即
自动重连,会抛出一个关于连接断开的异常,下次会自动重连。需确保每次操作Redis前正确的SELECT DB
。
- // config/database.php
- 'redis' => [
- 'default' => [
- 'host' => env('REDIS_HOST', 'localhost'),
- 'password' => env('REDIS_PASSWORD', null),
- 'port' => env('REDIS_PORT', 6379),
- 'database' => 0,
- 'persistent' => true, // 开启持久连接
- ],
- ],
- //...
你声明的全局、静态变量必须手动清理或重置。
无限追加元素到静态或全局变量中,将导致内存爆满。
- // 某类
- class Test
- {
- public static $array = [];
- public static $string = '';
- }
- // 某控制器
- public function test(Request $req)
- {
- // 内存爆满
- Test::$array[] = $req->input('param1');
- Test::$string .= $req->input('param2');
- }