注意事项

  • 单例问题

    • 传统FPM下,单例模式的对象的生命周期仅在每次请求中,请求开始=>实例化单例=>请求结束后=>单例对象资源回收。

    • Swoole Server下,所有单例对象会常驻于内存,这个时候单例对象的生命周期与FPM不同,请求开始=>实例化单例=>请求结束=>单例对象依旧保留,需要开发者自己维护单例的状态。

    • 如果你的项目中使用到了Session、Authentication、JWT,请根据情况解除laravels.phpcleaners的注释。

    • 常见的解决方案:

      • 写一个XxxCleaner类来清理单例对象状态,此类需实现接口Hhxsv5\LaravelS\Illuminate\Cleaners\CleanerInterface,然后注册到laravels.phpcleaners中。

      • 用一个中间件重置单例对象的状态。

      • 如果是以ServiceProvider注册的单例对象,可添加该ServiceProviderlaravels.phpregister_providers中,这样每次请求会重新注册该ServiceProvider,重新实例化单例对象,参考

  • 常见问题

  • 应通过Illuminate\Http\Request对象来获取请求信息,$_ENV是可读取的,$_SERVER是部分可读的,不能使用$_GET、$_POST、$_FILES、$_COOKIE、$_REQUEST、$_SESSION、$GLOBALS。

  1. public function form(\Illuminate\Http\Request $request)
  2. {
  3. $name = $request->input('name');
  4. $all = $request->all();
  5. $sessionId = $request->cookie('sessionId');
  6. $photo = $request->file('photo');
  7. // 调用getContent()来获取原始的POST body,而不能用file_get_contents('php://input')
  8. $rawContent = $request->getContent();
  9. //...
  10. }
  • 推荐通过返回Illuminate\Http\Response对象来响应请求,兼容echo、vardump()、print_r(),不能使用函数像 dd()、exit()、die()、header()、setcookie()、http_response_code()。
  1. public function json()
  2. {
  3. return response()->json(['time' => time()])->header('header1', 'value1')->withCookie('c1', 'v1');
  4. }
  • 各种单例的连接将被常驻内存,建议开启持久连接

  • 数据库连接,连接断开后会自动重连

  1. // config/database.php
  2. 'connections' => [
  3. 'my_conn' => [
  4. 'driver' => 'mysql',
  5. 'host' => env('DB_MY_CONN_HOST', 'localhost'),
  6. 'port' => env('DB_MY_CONN_PORT', 3306),
  7. 'database' => env('DB_MY_CONN_DATABASE', 'forge'),
  8. 'username' => env('DB_MY_CONN_USERNAME', 'forge'),
  9. 'password' => env('DB_MY_CONN_PASSWORD', ''),
  10. 'charset' => 'utf8mb4',
  11. 'collation' => 'utf8mb4_unicode_ci',
  12. 'prefix' => '',
  13. 'strict' => false,
  14. 'options' => [
  15. // 开启持久连接
  16. \PDO::ATTR_PERSISTENT => true,
  17. ],
  18. ],
  19. //...
  20. ],
  21. //...
  • Redis连接,连接断开后不会立即自动重连,会抛出一个关于连接断开的异常,下次会自动重连。需确保每次操作Redis前正确的SELECT DB
  1. // config/database.php
  2. 'redis' => [
  3. 'default' => [
  4. 'host' => env('REDIS_HOST', 'localhost'),
  5. 'password' => env('REDIS_PASSWORD', null),
  6. 'port' => env('REDIS_PORT', 6379),
  7. 'database' => 0,
  8. 'persistent' => true, // 开启持久连接
  9. ],
  10. ],
  11. //...
  • 你声明的全局、静态变量必须手动清理或重置。

  • 无限追加元素到静态或全局变量中,将导致内存爆满。

  1. // 某类
  2. class Test
  3. {
  4. public static $array = [];
  5. public static $string = '';
  6. }
  7.  
  8. // 某控制器
  9. public function test(Request $req)
  10. {
  11. // 内存爆满
  12. Test::$array[] = $req->input('param1');
  13. Test::$string .= $req->input('param2');
  14. }