首页 > 作文

不用三方包 给 Laravel 开启 Swoole

更新时间:2023-04-08 12:08:51 阅读: 评论:0

swoole是一款优秀的 php 扩展,利用其可以实现原生 php 很难做到的常驻服务和异步。正好我有个 laravel 项目可以折腾,就研究了下。

laravel 项目是基于 compor 的,所以我先帖下我的compor.json中的 require 声明:

{    "require": {        "php": "^7.1.3",        "cybercog/laravel-love": "^5.1",        "dingo/api": "~v2.0.0-alpha2",        "doctrine/dbal": "^2.8",        "fideloper/proxy": "^4.0",        "guzzlehttp/guzzle": "^6.3",        "infyomlabs/adminlte-templates": "5.6.x-dev",        "infyomlabs/laravel-generator": "5.6.x-dev",        "jeroennoten/laravel-adminlte": "^1.23",        "laravel/framework": "5.6.*",        "laravel/tinker": "^1.0",        "laravelcollective/html": "^5.6.0",        "lshorz/luocaptcha": "^1.0",        "overtrue/laravel-lang": "v3.0.08",        "overtrue/laravel-wechat": "^4.0",        "predis/predis": "^1.1",        "spatie/laravel-permission": "^2.17",        "tymon/jwt-auth": "~1.0.0-rc.2",        "yajra/laravel-datatables-buttons": "^4.0",        "yajra/laravel-datatables-oracle": "^8.7"    }}

  

如果我们要开启 swoole,我们可选的包有这些:

swooletw/laravel-swoolehhxsv5/laravel-s

但一般来说,项目中需要常驻容器的服务与每次均需重新构建的服务并不一样,所以我才剑走偏锋。

起步

我们需要将public/index.php替换成如下

<?phpu illuminate\http\request;u illuminate\http\respon;define('laravel_start', microtime(true));require __dir__ . '/../vendor/autoload.php';$app = require_once __dir__ . '/../bootstrap/app.php';class laravel{    /**     * illuminate\foundation\application     *     * @var \illuminate\foundation\application     */    public $app;    /**     * app\http\kernel     *     * @var \app\http\kernel     */    public $kernel;    /**     * app\http\requests\request     *     * @var \app\http\requests\request     */    public $request;    /**     * illuminate\http\jsonrespon     *     * @var \illuminate\http\jsonrespon     */    public $respon;    /**     * 构造     *     * @param \illuminate\foundation\application $app     */    public function __construct(\illuminate\foundation\application $app)    {        $this->app = $app;    }    /**     * run     *     * @return void 艺术符号    */    public function run()    {        \swoole\runtime::enablecoroutine(true);        $http = new swoole_http_rver('127.0.0.1', '80');        $http->t([            'document_root' => public_path('/'),            'enable_static_handler' => true,        ]);        $http->on('request', function ($req, $res) {            try {                $kernel = $this->app->make(illuminate\contracts\http\kernel::class);                $get = $req->get ?? [];                $post = $req->post ?? [];                $input = array_merge($get, $post);                $cookie = $req->cookie ?? [];                $files = $req->files ?? [];                $rver = $req->rver ?? [];                $request = request::create($req->rver['request_uri'], $req->rver['request_method'], $input, $cookie, $files, $rver);                if (ist($req->header['x-requested-with']) && $req->header['x-requested-with'] == "xmlhttprequ守茁est") {                    $request->headers->t('x-requested-with', "xmlhttprequest", true);                }                if (ist($req->header['accept']) && $req->header['accept']) {                    $request->headers->t('accept', $req->header['accept'], true);                }                $respon = $kernel->handle($request);                $res->status($respon->getstatuscode());                foreach ($respon->headers->allprervecawithoutcookies() as $name => $values) {                    foreach ($values as $value) {                        $res->header($name, $value, fal);                    }                }                foreach ($respon->headers->getcookies() as $cookie) {                    $res->header('t-cookie', $cookie->getname() . strstr($cookie, '='), fal);                }                dump(time());                $res->end($respon->getcontent());                $this->app->forgetinstance('request');            } catch (\throwable $e) {                echo $e->getmessage();                echo php_eol;                echo $e->getfile();                echo php_eol;                echo $e->getline();                echo php_eol;            }        });        $http->start();    }}(new laravel($app))->run();

  

运行时发现大多数页面均没有问题,只有几个用了infyomlabs/laravel-generator产生的列表页,ajax 拉取 json 时却返回了 html。

排查

在有问题页面的 controller 代码中,找到如下

 /**     * display a listing of the star.     *     * @param stardatatable $stardatatable     * @return respon     */    public function index(stardatatable $stardatatable)    {        return $stardatatable->render('stars.index');    }定位 stardatatable::render() 到了  /**     * process datatables needed render output.     *     * @param string $view     * @param array $data     * @param array $mergedata     * @return mixed     */    public function render($view, $data = [], $mergedata = [])    {        if ($this->request()->ajax() && $this->request()->wantsjson()) {            return app()->call([$this, 'ajax']);        }        ...    }

  

这是判断$this-&冶金学院gt;request()是不是 xhr 请求,且accept请求头声明了application/json

$this->request()实现如下

    /**     * get datatables request instance.     *     * @return \yajra\datatables\utilities\request     */    public function request()    {        return $this->request ?: $this->request = resolve('datatabl孩子教育问题es.request');    }

  

不难看出,如果第一次构建,会走到

$this->request = resolve('datatables.request');

  

而 resolve 的实现是啥?

if (! function_exists('resolve')) {    /**     * resolve a rvice from the container.     *     * @param  string  $name     * @return mixed     */    function resolve($name)    {        return app($name);    }}

  

就是从容器中取出datatables.request的过程。

所以我们只需让每次请求结束,$app 容器忘掉datatables.request就好了

改进

增加遗忘datatables.request

    $res->end($respon->getcontent());    $this->app->forgetinstance('request');    $this->app->forgetinstance('datatables.request');    $this->app->forgetinstance(\dingo\api\http\middleware\request::class);

  

完整最终版:

<?phpu illuminate\http\request;u illuminate\http\respon;define('laravel_start', microtime(true));require __dir__ . '/../vendor/autoload.php';$app = require_once __dir__ . '/../bootstrap/app.php';class laravel{    /**     * illuminate\foundation\application     *     * @var \illuminate\foundation\application     */    public $app;    /**     * app\http\kernel     *     * @var \app\http\kernel     */    public $kernel;    /**     * app\http\requests\request     *     * @var \app\http\requests\request     */    public $request;    /**     * illuminate\http\jsonrespon     *     * @var \illuminate\http\jsonrespon     */    public $respon;    /**     * 构造     *     * @param \illuminate\foundation\application $app     */    public function __construct(\illuminate\foundation\application $app)    {        $this->app = $app;    }    /**     * run     *     * @return void     */    public function run()    {        \swoole\runtime::enablecoroutine(true);        $http = new swoole_http_rver('127.0.0.1', '80');        $http->t([            'document_root' => public_path('/'),            'enable_static_handler' => true,        ]);        $http->on('request', function ($req, $res) {            try {                $kernel = $this->app->make(illuminate\contracts\http\kernel::class);                $get = $req->get ?? [];                $post = $req->post ?? [];                $input = array_merge($get, $post);                $cookie = $req->cookie ?? [];                $files = $req->files ?? [];                $rver = $req->rver ?? [];                $request = request::create($req->rver['request_uri'], $req->rver['request_method'], $input, $cookie, $files, $rver);                if (ist($req->header['x-requested-with']) && $req->header['x-requested-with'] == "xmlhttprequest") {                    $request->headers->t('x-requested-with', "xmlhttprequest", true);                }                if (ist($req->header['accept']) && $req->header['accept']) {                    $request->headers->t('accept', $req->header['accept'], true);                }                $respon = $kernel->handle($request);                $res->status($respon->getstatuscode());                foreach ($respon->headers->allprervecawithoutcookies() as $name => $values) {                    foreach ($values as $value) {                        $res->header($name, $value, fal);                    }                }                foreach ($respon->headers->getcookies() as $cookie) {                    $res->header('t-cookie', $cookie->getname() . strstr($cookie, '='), fal);                }                dump(time());                $res->end($respon->getcontent());                $this->app->forgetinstance('request');                //$this->app->forgetinstance('ssion');                //$this->app->forgetinstance('ssion.store');                //$this->app->forgetinstance('cookie');                $this->app->forgetinstance('datatables.request');                $this->app->forgetinstance(\dingo\api\http\middleware\request::class);                //$kernel->terminate($request, $respon);            } catch (\throwable $e) {                echo $e->getmessage();                echo php_eol;                echo $e->getfile();                echo php_eol;                echo $e->getline();                echo php_eol;            }        });        $http->start();  中国记忆大师  }}(new laravel($app))->run();

  

测试

比原生 laravel 确实快不少(这还有 4 句 sql 查询) 。

注,此处给出的代码可以借鉴,但未经长期验证。且不同项目实际用到的包不同,需要在调试过程中debug容器中的服务提供者,和追踪代码来调优。

已知问题

flash 闪存数据以及表单验证错误的展示有问题pdo 会报 cannot execute queries while other unbuffered queries are activesymfony/symfony…throttle 的 ip 获取设定默认会产生问题

更多学习内容请访问:

腾讯t3-t4标准精品php架构师教程目录大全,只要你看完保证薪资上升一个台阶(持续更新)

本文发布于:2023-04-08 12:08:49,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/zuowen/97a352a957f397cc0d50a1057902e5cb.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

本文word下载地址:不用三方包 给 Laravel 开启 Swoole.doc

本文 PDF 下载地址:不用三方包 给 Laravel 开启 Swoole.pdf

标签:项目   容器   代码   会报
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图