我还是希望群主能想办法,把这个action-hook应该改为 全局中间件->用户应用中间件->路由中间件-> action-hook中间件->控制器的某个方法,就想__consturct一样,但是我又不想 关闭 控制器复用模式,
<?php
return [
'' => [
\app\middleware\AccessOptionRequestMiddleware::class
],
'app_admin'=>[
\app\app_admin\MiddlewareAppAdmin::class
],
'app_user'=>[
\app\app_user\MiddlewareAppUser::class
],
];
<?php
namespace app\app_admin;
use app\api\service\JwtService;
use app\api\service\ResponseJson;
use app\ConstMap\HttpStatusConst;
use app\ConstMap\JwtConst;
use Webman\Http\Request;
use Webman\Http\Response;
use Webman\MiddlewareInterface;
class MiddlewareAppAdmin implements MiddlewareInterface
{
public function process(Request $request, callable $handler): Response
{
return \response('不执行这里');
}
}
<?php
namespace app\app_admin\controller;
use app\model\Recharge;
use app\model\Users;
use support\Request;
use Webman\View;
class AdminDashboard
{
public function beforeAction(Request $request){
var_dump('111');
// \support\View::assign('username',Users::where('uid',$request->jwt->uid)->value('username'));
}
}
var_dump(111);
\response('不执行这里');
docker
你会不会url访问错了?
我已经找到原因了,因为 action-hook插件会注册,全局中间件,我自己的应用中间件是后执行的,应用中间件里我加了$request->jwt 变量传递,action-hook先执行 public function beforeAction当然就报错了。
我还是希望群主能想办法,把这个action-hook应该改为 全局中间件->用户应用中间件->路由中间件-> action-hook中间件->控制器的某个方法,就想__consturct一样,但是我又不想 开启 控制器复用模式
action-hook插件时为了解决控制器复用时__consturct无法执行问题。目前webman已经支持关闭复用控制器了,action-hook已经不推荐用了,推荐关闭控制器复用,使用__consturct。
为了给过时的action-hook插件开绿灯更改内核不是好主意。
如果关闭了复用控制器,会导致 每次都new std(),因为静态变量持久化内存的特性,现在的代码都是把一些 从数据库读取的信息 永久储存在 控制器静态变量中。
目前我手动在/config/action-hook/app.php 中关闭了enable,并且人工在 /config/middleware.php中注册顺序。
我目前就是有个疑问,在composer install的时候,会不会更改或覆盖 /config/action-hook/app.php 文件
composer install 不会更改config/plugin中已经存在的配置
@admin 我后来升级到最新,也是想关闭控制器复用,碰到的问题和你一样,所以还是用action-hook。同时,我想问一下,假如,两4个进程,是不是就有4个控制器常驻内存?也就是控制器里的静态变量也有四份?
需要持久保存的数据放在静态属性里,然后关闭控制器复用。这样即持久化保存了数据,又能每个请求自动调用__construct()初始化控制器实例。控制器静态属性保存数据和关闭控制器复用没有冲突。
@oscar 4个进程完全独立的,互相不影响,每个进程有自己的常住内存控制器,静态变量也是四份
控制器复用,直接取消了更好。
复用的时候需要在请求结束处理里面的用户数据,省内存和避免程序bug导致数据被下一个用户拿到。
但是如果复用但是不在里面存数据,那复用也没多大用,就是节省了new 的开销。
开启控制器复用,控制器里面可以存一些公共数据,公共数据不需要请求结束时处理,这样没任何问题。
如果需要控制器存当前请求状态数据,每次请求后需要清理,所以这种情况还是不开的好。
不要小看这个new开销,关闭控制器复用,helloworld压力测试QPS降低20-30%左右,带数据库业务性能降低10%左右。
公共数据没必要存控制器,单独弄一个类,搞静态属性。不然浪费内存,每个控制器4份,然后几十上百个控制器。
除非所谓的公共数据是每个控制器独有的。
难道 你单独的静态类 不是4份? 不是每个进程一份?难道是每个进程用同一份?那怎么没做锁呢
区别就是单独放一个类里,几个进程就几份。你放控制器里,这个数字还要再乘以你的控制器数量。
控制器默认是复用的不会出现你说的情况,即控制器::$StaticVal
你说的是静态属性,那挂任何类上都是一样的,包括控制器。既然是静态属性,就跟new不new无关。
@喵了个咪
不要小看这个new开销,关闭控制器复用,helloworld压力测试QPS降低20-30%左右,带数据库业务性能降低10%左右。
说实在的,一个框架里面要new的东西估计有点多。
如果new一个控制器就有那么大影响,那真的是应该都用静态方法了,这样就不需要new。
设想一下,假如开了控制复用,控制器里面有个helloworld方法。
你看,开启复用了,但是每次执行都new 了一个
\app\common\helloworldService
来处理请求,可能我在doSomething
里面有new了一堆其他东西。所以new控制器节省的那点性能,是真实的吗?估计你的测试就是 return 'helloworld'吧。
除非你要求程序员处理请求的过程中不要new 任何东西,我觉得不现实。
好吧,我把
helloworldService
弄成静态属性了,这样就不用每次都new一次了。但是
doSomething
仍然不是静态的呀,万一在里面new了其他东西呢?把helloworldService的doSomething也搞静态化?
所以还是那句话:
除非你要求程序员处理请求的过程中不要new 任何东西,我觉得不现实。这个要求有点过分!
@喵了个咪
你节省的new控制器的那点开销,只要后面过程中有任何一个new,就被抵消了。
就算你写的代码全程静态方法静态属性,复用控制器以后不需要重复new任何东西。
但是你不使用composer的东西吗?
第三方库里面也许会给你new个东西出来吧!
哈哈,气不气呀。
所以我觉得这个框架节省的应该是类加载的开销,而不是new的开销。
我上面表达的观点是站在框架角度,不要小看这个new开销。当然你站在分业务角度,多一个new确实所谓。
关闭控制器复用,webman可以做到一个请求几乎不new任何东西的。
大部分业务中节省一个new确实没意义,但是站在框架角度,框架因节省一个new将极限性能提升20-30%意义很大
所以webman框架应该支持控制器复用的功能,你可以关闭它不用,但是不能像你说的直接取消它。
整个流程中的几次方法调用,能做到保持相同的姿势,不使用[方式1]?
我再重申一遍,我是站在框架角度,框架支持控制器复用减少一次new调用能让框架极限性能提升20-30%,对于框架而言是值得的,它能提升框架性能上限,不能像你说的取消支持控制器复用功能,我只是表达这个观点。
至于你自己的业务怎么怎么调用,不在我的讨论范畴。
站在框架的角度,不能只看到性能的提升。
框架底层逻辑是有的区别,这是可能会产生一些差异的,不能只看到是性能的差异。
在未开启控制器复用的情况下,如果安装了
action-hook
插件,是会拖慢性能的。当然,现在修复了,未开启控制器复用但安装了
action-hook
,不会生效而已也不拖性能。https://github.com/webman-php/action-hook/pull/2
你要觉得我在装逼,那也没办法。
你们不要再打了