我還是希望群主能想辦法,把這個action-hook應(yīng)該改為 全局中間件->用戶應(yīng)用中間件->路由中間件-> action-hook中間件->控制器的某個方法,就想__consturct一樣,但是我又不想 關(guān)閉 控制器復(fù)用模式,
<?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('不執(zhí)行這里');
}
}
<?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('不執(zhí)行這里');
docker
你會不會url訪問錯了?
我已經(jīng)找到原因了,因為 action-hook插件會注冊,全局中間件,我自己的應(yīng)用中間件是后執(zhí)行的,應(yīng)用中間件里我加了$request->jwt 變量傳遞,action-hook先執(zhí)行 public function beforeAction當然就報錯了。
我還是希望群主能想辦法,把這個action-hook應(yīng)該改為 全局中間件->用戶應(yīng)用中間件->路由中間件-> action-hook中間件->控制器的某個方法,就想__consturct一樣,但是我又不想 開啟 控制器復(fù)用模式
action-hook插件時為了解決控制器復(fù)用時__consturct無法執(zhí)行問題。目前webman已經(jīng)支持關(guān)閉復(fù)用控制器了,action-hook已經(jīng)不推薦用了,推薦關(guān)閉控制器復(fù)用,使用__consturct。
為了給過時的action-hook插件開綠燈更改內(nèi)核不是好主意。
如果關(guān)閉了復(fù)用控制器,會導(dǎo)致 每次都new std(),因為靜態(tài)變量持久化內(nèi)存的特性,現(xiàn)在的代碼都是把一些 從數(shù)據(jù)庫讀取的信息 永久儲存在 控制器靜態(tài)變量中。
目前我手動在/config/action-hook/app.php 中關(guān)閉了enable,并且人工在 /config/middleware.php中注冊順序。
我目前就是有個疑問,在composer install的時候,會不會更改或覆蓋 /config/action-hook/app.php 文件
@admin 我后來升級到最新,也是想關(guān)閉控制器復(fù)用,碰到的問題和你一樣,所以還是用action-hook。同時,我想問一下,假如,兩4個進程,是不是就有4個控制器常駐內(nèi)存?也就是控制器里的靜態(tài)變量也有四份?
需要持久保存的數(shù)據(jù)放在靜態(tài)屬性里,然后關(guān)閉控制器復(fù)用。這樣即持久化保存了數(shù)據(jù),又能每個請求自動調(diào)用__construct()初始化控制器實例??刂破黛o態(tài)屬性保存數(shù)據(jù)和關(guān)閉控制器復(fù)用沒有沖突。
控制器復(fù)用,直接取消了更好。
復(fù)用的時候需要在請求結(jié)束處理里面的用戶數(shù)據(jù),省內(nèi)存和避免程序bug導(dǎo)致數(shù)據(jù)被下一個用戶拿到。
但是如果復(fù)用但是不在里面存數(shù)據(jù),那復(fù)用也沒多大用,就是節(jié)省了new 的開銷。
開啟控制器復(fù)用,控制器里面可以存一些公共數(shù)據(jù),公共數(shù)據(jù)不需要請求結(jié)束時處理,這樣沒任何問題。
如果需要控制器存當前請求狀態(tài)數(shù)據(jù),每次請求后需要清理,所以這種情況還是不開的好。
不要小看這個new開銷,關(guān)閉控制器復(fù)用,helloworld壓力測試QPS降低20-30%左右,帶數(shù)據(jù)庫業(yè)務(wù)性能降低10%左右。
公共數(shù)據(jù)沒必要存控制器,單獨弄一個類,搞靜態(tài)屬性。不然浪費內(nèi)存,每個控制器4份,然后幾十上百個控制器。
除非所謂的公共數(shù)據(jù)是每個控制器獨有的。
公共數(shù)據(jù)沒必要存控制器,單獨弄一個類,搞靜態(tài)屬性。不然浪費內(nèi)存,每個控制器4份,然后幾十上百個控制器。
難道 你單獨的靜態(tài)類 不是4份? 不是每個進程一份?難道是每個進程用同一份?那怎么沒做鎖呢
你說的是靜態(tài)屬性,那掛任何類上都是一樣的,包括控制器。既然是靜態(tài)屬性,就跟new不new無關(guān)。
protected static $Val1;//靜態(tài)屬性 份數(shù)=進程數(shù),new無關(guān),復(fù)用與不復(fù)用無區(qū)別
protected $Val2;//非靜態(tài)屬性 份數(shù)=進程*控制器數(shù),new相關(guān),復(fù)用與不復(fù)用有區(qū)別
@喵了個咪
不要小看這個new開銷,關(guān)閉控制器復(fù)用,helloworld壓力測試QPS降低20-30%左右,帶數(shù)據(jù)庫業(yè)務(wù)性能降低10%左右。
說實在的,一個框架里面要new的東西估計有點多。
如果new一個控制器就有那么大影響,那真的是應(yīng)該都用靜態(tài)方法了,這樣就不需要new。
設(shè)想一下,假如開了控制復(fù)用,控制器里面有個helloworld方法。
public function helloworld()
{
$servcice =new \app\common\helloworldService;
$response = $servcice->doSomething();
return $response;
}
你看,開啟復(fù)用了,但是每次執(zhí)行都new 了一個\app\common\helloworldService
來處理請求,可能我在doSomething
里面有new了一堆其他東西。
所以new控制器節(jié)省的那點性能,是真實的嗎?估計你的測試就是 return 'helloworld'吧。
除非你要求程序員處理請求的過程中不要new 任何東西,我覺得不現(xiàn)實。
好吧,我把helloworldService
弄成靜態(tài)屬性了,這樣就不用每次都new一次了。
protected static $servcice;
public function __construct()
{
$this->servcice =new \app\common\helloworldService;
}
public function helloworld()
{
$response = $this->servcice->doSomething();
return $response;
}
但是doSomething
仍然不是靜態(tài)的呀,萬一在里面new了其他東西呢?
把helloworldService的doSomething也搞靜態(tài)化?
所以還是那句話:
除非你要求程序員處理請求的過程中不要new 任何東西,我覺得不現(xiàn)實。這個要求有點過分!
@喵了個咪
你節(jié)省的new控制器的那點開銷,只要后面過程中有任何一個new,就被抵消了。
就算你寫的代碼全程靜態(tài)方法靜態(tài)屬性,復(fù)用控制器以后不需要重復(fù)new任何東西。
但是你不使用composer的東西嗎?
第三方庫里面也許會給你new個東西出來吧!
哈哈,氣不氣呀。
所以我覺得這個框架節(jié)省的應(yīng)該是類加載的開銷,而不是new的開銷。
我上面表達的觀點是站在框架角度,不要小看這個new開銷。當然你站在分業(yè)務(wù)角度,多一個new確實所謂。
關(guān)閉控制器復(fù)用,webman可以做到一個請求幾乎不new任何東西的。
大部分業(yè)務(wù)中節(jié)省一個new確實沒意義,但是站在框架角度,框架因節(jié)省一個new將極限性能提升20-30%意義很大
所以webman框架應(yīng)該支持控制器復(fù)用的功能,你可以關(guān)閉它不用,但是不能像你說的直接取消它。
class Somecontroller
{
protected $thing2;
protected static $thing3;
public function __construct()
{
$this->thing2 = new someThing;
if (!static::$thing3) {
static::$thing3 = new someThing;
}
}
public function someFunctin()
{
//方式1,直接new,每次調(diào)用此方法都重新new
$thing1 = new someThing;
$response = $thing1->someFunctin();
//方式2,內(nèi)部屬性,不用每次都new。
$response = $this->thing2->someFunctin();
//方式3,靜態(tài)屬性,不用每次都new。
$response = static::$thing3->someFunctin();
//方式4,使用容器生產(chǎn)實例,應(yīng)該和3等效吧
$response = $container->make(someThing::class)->someFunctin();
return $response;
}
}
class SomeThing
{
public function someFunctin()
{
//這里用需要用到SomeThing2的someFunctin2
//和上面類似
}
}
class SomeThing2
{
public function someFunctin2()
{
//這里用需要用到SomeThing3的someFunctin3
//和上面類似
}
}
class SomeThing3
{
public function someFunctin3()
{
//這里用需要用到SomeThing4的someFunctin4
//和上面類似
}
}
class SomeThing4
{
//1個請求用到3~4個類不夸張吧
public function someFunctin4()
{
//這里使用了一個composer的東西,超出控制范圍了,它里面可能new了什么東西,我不可能去改它
}
}
整個流程中的幾次方法調(diào)用,能做到保持相同的姿勢,不使用[方式1]?
我再重申一遍,我是站在框架角度,框架支持控制器復(fù)用減少一次new調(diào)用能讓框架極限性能提升20-30%,對于框架而言是值得的,它能提升框架性能上限,不能像你說的取消支持控制器復(fù)用功能,我只是表達這個觀點。
至于你自己的業(yè)務(wù)怎么怎么調(diào)用,不在我的討論范疇。
站在框架的角度,不能只看到性能的提升。
框架底層邏輯是有的區(qū)別,這是可能會產(chǎn)生一些差異的,不能只看到是性能的差異。
在未開啟控制器復(fù)用的情況下,如果安裝了action-hook
插件,是會拖慢性能的。
當然,現(xiàn)在修復(fù)了,未開啟控制器復(fù)用但安裝了action-hook
,不會生效而已也不拖性能。
https://github.com/webman-php/action-hook/pull/2
你要覺得我在裝逼,那也沒辦法。