[Swoole] 結合 Laravel 與 Swoole,更簡易的開發與佈署!(未完成)

前情提要

前陣子在寫 golang,因為寫完之後直接 build 就可以放到伺服器上覺得很方便,所以一直在想 PHP 有沒有辦法做到這樣的開發/佈署流程。

就我研究 Docker 的經驗看起來,PHP 確實是有這個潛力的,不過感覺就差那麼最後一哩路。

直到我看到了 韓天峰:2017 年 PHP 程序员未来路在何方 中提到了 Swoole,頓時感到醍醐灌頂,內牛滿面,這不正是我苦苦追尋的那最後一哩路嗎?

構想

Swoole 實現了 HTTP Server,也就是說 PHP 的佈署不再需要依賴 Nginx 或 Apache 這樣的網頁伺服器,也不需要靠著 PHP-FPM 或 PHP_mod 才能與 Web Server 溝通。

安裝了 Swoole extension 後的 PHP,就像 golang 那般內建高效率的 HTTP Server(不是像 PHP Built-in Server 那種閹割後的太監玩意,是效能與 Nginx 媲美的 Web Server!)

甚至,只要用一個簡單的 Dockerfile 就可以實現佈署的流程,再也不需要 link nginx 又 link php-fpm,把 Dockerfile 弄得跟蜘蛛網一樣複雜。

只要一個 Dockerfile,就能夠完成 Web Server 跟應用程式佈署,多開心吶。

FROM php:cli
COPY project /var/www/project

CMD ["php", "/var/www/project/index.php"]

結合 Laravel?

說到底,如果用了 Swoole 還得重複造輪子,那這玩意還是沒啥屁用。

可是如果它能夠結合當今最火紅的 PHP Web Framework:Laravel,我想一切都不太一樣了。

實作

Step 1. 取得 Laravel

先從 github 上 clone 最新版本的 laravel 下來。

Step 2. 修改 index.php

Laravel 的程式進入點位於 public/index.php 我們也只會變更到這個檔案

原本的檔案(移除註解):

<?php
require __DIR__.'/../bootstrap/autoload.php';

$app = require_once __DIR__.'/../bootstrap/app.php';

$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);

$response = $kernel->handle(
    $request = Illuminate\Http\Request::capture()
);

$response->send();

$kernel->terminate($request, $response);

修改過後:

<?php
require dirname(__DIR__).'/bootstrap/autoload.php';

// IP 跟 Port 可以自行調整
// 如果要監聽全部介面可以用 0.0.0.0
// port 小於 1024 需要 root 權限
$http = new Swoole\Http\Server('127.0.0.1', 9000);

$http->on('request', function (Swoole\Http\Request $request, Swoole\Http\Response $response) {
    /**
     * @var \Illuminate\Foundation\Application $app
     * @var \Illuminate\Contracts\Http\Kernel $kernel
     * @var \Illuminate\Http\Request $laravelRequest
     * @var \Illuminate\Http\Response $laravelResponse
     */
    $app = require dirname(__DIR__).'/bootstrap/app.php';
    $kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);

    $laravelResponse = $kernel->handle(
        $laravelRequest = new \Illuminate\Http\Request(
            $request->get ?? [],
            $request->post ?? [],
            [],
            $request->cookie ?? [],
            $request->files ?? [],
            $request->server ?? []
        )
    );

    $kernel->terminate($laravelRequest, $laravelResponse);

    $response->status($laravelResponse->getStatusCode());
    $response->write($laravelResponse->getContent());

    unset(
        $app,
        $kernel,
        $laravelResponse,
        $laravelRequest
    );
});

$http->start();

執行

php public/index.php 即可啟動

啟動前別忘了要設定好 .env

已知問題

  1. Laravel 應用程式無法取得網址與port

    這個值應該是位於 $request->server 裡面,但是不知道為什麼 Laravel 抓不到

本作品采用《CC 协议》,转载必须注明作者和本文链接
本帖由系统于 6年前 自动加精
讨论数量: 15
幽弥狂

就不需要再安装nginx等东西了????

7年前 评论

@xhh110 不需要 nginx 作為 Web Server

但是通常會在前面掛一個 Nginx 的反向代理,讓 Nginx 去處理 Gzip、Load Balance 之類的事

7年前 评论
leo

Request Session Cookie 都会有问题,参考 https://segmentfault.com/a/119000000789411...

7年前 评论

@leo 哎呀真是太感謝了 <()>

不忍說我也去找過輪子,不過實在苦於不知道該怎麼下關鍵字所以最後放棄了 QAQQ

7年前 评论

这样的轮子看到过不少,有基于 Swoole、有基于 Workerman,还有基于 PPM 的,不知道实际在生产环境投入使用的案例有多少。

7年前 评论

做web应用,能用lnmp做的就用lnmp。lnmp干不了的再考虑swoole workerman,当然我更推荐golang。
swoole在我理解是扩展了php的应用范围,而不是改变了原有的运行方式。改变原来的运行方式会付出很大的代价,因为是常驻内存,基本上以前用的轮子都要改造改造。你的编码行为,从原来的无所畏惧要变成小心翼翼(到底会不会内存泄露呢。。)

7年前 评论

Laravel 不是有 server 命令吗?

php artisan serve
7年前 评论

@Hanccc 我也是之後才發現有這個輪子的 XD

7年前 评论

@Boomdawn 其實不想用 LNMP 最大的原因在於佈署上的麻煩

如果 PHP 能像 Golang 在核心就直接實現 Http Server 的功能,在佈署時就只要專心在業務上就好(還省得去設定 nginx 跟 fpm 的連接等)

7年前 评论

@ety001 這個指令只能用於開發時期哦,它內部應該是靠 PHP Built-in Web Server 實現的

PHP 官方也不建議直接以 Built-in Web Server 跑在 Production 環境上,只建議在開發時使用

7年前 评论

swoole的request里面的server的uri是小写的。但laravel是通过大写获取的,所以要转一下

file

7年前 评论

可以应用到生产还有很长时间。如果觉得好玩可以做一些基于这个库的实验项目。

7年前 评论

描述:在一个新的laravel5.4中,按照本主题修改了public/index.php, 目前可以打开/home,随后我使用了php artisan make:auth及php artisan migrate,然后重新启动sudo php public/index.php
我的首页没有任何变化,右上方的login,register没有出现,我随后自建了一个简单的路由

Route::get('/test', function(){
    dd("swoole");
})

重启swoole服务后,输入/test,响应的仍旧是/home的laravel首页.

问题:请问你们出现这种情况了吗?

6年前 评论

我目前在造的轮子 LaravelS https://github.com/hhxsv5/laravel-s 通过 Swoole 来加速 Laravel/Lumen,有兴趣可以尝试下。

6年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!