[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
已知問題
- Laravel 應用程式無法取得網址與port
這個值應該是位於 $request->server 裡面,但是不知道為什麼 Laravel 抓不到
本作品采用《CC 协议》,转载必须注明作者和本文链接
推荐文章: