zhanguangcheng / yii2-workerman

The purpose is to run the Yii 2 framework in Workerman to implement the resident memory to improve the performance.
3 stars 1 forks source link

gii为什么不能用了,有解决办法么 #6

Closed xuellbcd closed 8 months ago

xuellbcd commented 10 months ago

Invalid Argument – yii\base\InvalidArgumentException The file or directory to be published does not exist: E:\myproject\yii2-workerman\vendor\yiisoft\yii2/gii/assets

zhanguangcheng commented 10 months ago

已修复:https://github.com/zhanguangcheng/yii2-workerman/commit/4d4080014a5bbb41077cf320613f07f012557ebc 感谢反馈

xuellbcd commented 10 months ago

已修复:4d40800 感谢反馈

谢谢大佬。这么快修复了。现在这一套东西,如果我用于生产环境,还有什么需要注意的地方么?因为对yii2比较熟悉,但是又觉得希望利用workerman的高性能。目前找到的两者结合的框架里边,您做的这个,我觉得可能是最简洁易用的了,但是目前不知道会不会有一些坑。之前我自己尝试过用workerman运行yii2,但是好像yii2的一些behaviors什么的,可能失效了

zhanguangcheng commented 10 months ago

目前我自己也是用这套开发新项目,还是比较有信心的。 其中的核心库Linkerman也是有完备的测试用例,以保障重写的函数的稳定性,包含请求参数($_GET/$_POST/$_FILES/$_COOKIE),cookie、session、响应头、文件上传等等。 目前已知不兼容地方:

  1. 不能使用pcntl_fork()函数(和workerman一致)
  2. 不能使用exit()die()(和workerman一致)
  3. file_get_contents("php://input")获取不到请求的原始数据,使用request_raw_body()代替
  4. register_shutdown_function()注册的回调函数不会在请求结束时执行,因为常驻内存了,使用register_shutdown_function_user()代替

其中3和4点在安装composer依赖时已经自动将Yii2源码替换了,无需关心。

另外就是需要注意异步的情况,2个请求同时处理,异步环境中的全局变量会被后面的覆盖,解决方法:使用use将变量传入,如

$xx = Yii::$app->request->get('xx');
$http = new Workerman\Http\Client();
$http->request('https://example.com/', [
    'method' => 'GET',
    'version' => '1.1',
    'headers' => ['Connection' => 'keep-alive'],
    'success' => function ($response) use($xx) {
        echo $xx;
    },
]);

发现问题欢迎提交issue,我会第一时间解决。

zhanguangcheng commented 10 months ago

behaviors可以正常使用,我使用PHP8的注解结合behaviors限制请求方法、请求限流,类似这样:

    /**
     * 发送短信验证码,有效期10分钟
     * @throws InvalidArgumentHttpException
     */
    #[AllowMethod('POST')]
    #[RateLimit(limit: 1, window: 10, type: RateLimit::BY_IP)]
    #[RateLimit(limit: 1, window: 60, type: RateLimit::BY_USER, message: '操作过于频繁,请一分钟后再试。')]
    public function actionSendSmsCode(): Response
    {
        $form = new SendSmsCodeForm();
        $form->load(post(), '');
        $connection = Yii::$app->connection;
        $form->send()
            ->then(fn($result) => $connection->send(rawStdResponse(200, '发送成功', $result)))
            ->catch(fn(Throwable $e) => $connection->send(rawStdResponse($e->getCode(), $e->getMessage())));
        return asyncResponse();
    }