sdpmlab/ codeigniter4-roadrunner
使Codeigniter4在Roadrunner服务器上运行。
Requires
- php: ^7.4 || ^8.0
- codeigniter4/framework: ^4.2.0
- laminas/laminas-diactoros: ^2.8
- nyholm/psr7: ^1.4
- spiral/dumper: ^2.8
- spiral/roadrunner: ^2
Requires (Dev)
- codeigniter4/devkit: ^1.0
- rector/rector: 0.12.16
This package is auto-updated.
Last update: 2024-09-22 23:43:31 UTC
README
Codeigniter4-RoadRunner提供了Roadrunner-Worker和Codeigniter4之间请求和响应对象的同步。由于Codeigniter4没有完全实现PSR-7标准,您需要使用此库以允许您的Codeigniter4项目在RoadRunner服务器上运行。
安装
先决条件
- CodeIgniter框架4.2.0^
- Composer
- 启用
php-curl
扩展 - 启用
php-zip
扩展 - 启用
php-sockets
扩展
Composer安装
使用"Composer"下载库及其依赖项到项目
composer require sdpmlab/codeigniter4-roadrunner
使用库内置命令初始化Roadrunner和文件
php spark ciroad:init
运行
在项目根目录运行命令
- 在Windows上使用Roadrunner命令
rr.exe serve -d
- 在MacOS/Linux上使用Roadrunner命令
./rr serve -d
服务器设置
服务器设置都在项目根目录的".rr.yaml"中。默认文件看起来像这样
version: "2.7" rpc: listen: tcp://127.0.0.1:6001 server: command: "php psr-worker.php" # env: # XDEBUG_SESSION: 1 http: address: "0.0.0.0:8080" static: dir: "./public" forbid: [".htaccess", ".php"] pool: num_workers: 1 # max_jobs: 64 # debug: true # reload: # interval: 1s # patterns: [ ".php" ] # services: # http: # recursive: true # ignore: [ "vendor" ] # patterns: [ ".php", ".go", ".md" ] # dirs: [ "." ]
您可以根据Roadrunner文档创建自己的配置文件。
开发建议
自动重新加载
在RoadRunner的默认情况下,每次您修改任何PHP文件后都必须重新启动服务器,以便您的修改生效。这在开发过程中似乎并不友好。
您可以通过修改.rr.yaml
配置文件,添加以下设置,并用-d
启动开发模式。RoadRunner服务器将自动检测PHP文件是否已修改,并立即重新加载Worker。
reload: interval: 1s patterns: [ ".php" ] services: http: recursive: true ignore: [ "vendor" ] patterns: [ ".php", ".go", ".md" ] dirs: [ "." ]
reload
功能非常消耗资源,请勿在正式环境中激活此选项。
使用Codeigniter4请求和响应对象
Codeigniter4没有完全实现HTTP消息接口,因此此库专注于PSR-7接口
和Codeigniter4 HTTP接口
的同步。
基于上述原因,您应使用Codeigniter4提供的$this->request
或全局函数/Config/Services::('request')
来获取正确的请求对象;使用$this->response
或/Config/Services::('response')
来获取正确的响应对象。
请注意,在开发过程中构建响应时,您应避免使用PHP内置方法进行header
或set-cookies
设置。使用由Codeigniter4响应对象提供的setHeader()
和setCookie()
进行设置。
使用return停止控制器逻辑
在控制器内部,尝试使用return停止控制器逻辑。无论是对视图还是API的响应,减少echo
输出的使用可以避免许多错误,就像这样
<?php namespace App\Controllers; use CodeIgniter\API\ResponseTrait; class Home extends BaseController { use ResponseTrait; public function index() { // Don't use: // echo view('welcome_message'); return view('welcome_message'); } /** * send header */ public function sendHeader() { $this->response->setHeader("X-Set-Auth-Token", uniqid()); return $this->respond(["status"=>true]); } }
使用内置的Session库
我们只专注于支持Codeigniter4内置的Session库,并无法保证使用session_start()
和$_SEEEION
可以正常工作。因此,您应避免使用PHP内置的Session方法,改用Codeigniter4框架内置的库。
在仅有一个Worker的环境中开发和调试
由于RoadRunner与其它服务器软件(例如Nginx、Apache)在本质上存在差异,每个Codeigniter4实例都将作为Worker形式存在于RAM中。HTTP请求会复用这些Worker来处理。因此,我们最好在只有一个Worker的环境下开发和测试稳定性,以证明它也能在正式环境下的多个Worker中正常运行。
您可以参考以下.rr.yaml
设置来将Worker的数量降至最低
http: address: "0.0.0.0:8080" static: dir: "./public" forbid: [".htaccess", ".php"] pool: num_workers: 1 # max_jobs: 64 # debug: true
数据库连接
我们只关注支持Codeigniter4内置的数据库库,因此我们不保证使用PHP内置方法是否能够正常工作。因此,您应该避免使用PHP内置的数据库连接方法,而是选择Codeigniter4框架内置的库。
在默认情况下,Worker的数据库连接应该是持久的,并在连接失败时尝试重新连接。每个进入Worker的请求都会使用相同的数据库连接实例。如果您不想使用此默认设置,而是希望每个请求都使用重新连接的数据库连接实例,您可以将在根目录下的.env
文件中添加以下配置。
CIROAD_DB_AUTOCLOSE = true
全局方法
我们提供了一些全局方法,以帮助您更顺畅地开发项目。
处理文件上传
由于RoadRunner Worker无法传递正确的$_FILES
上下文,Codeigniter4文件上传类将无法正常工作。为了解决这个问题,我们为您提供了一个符合PSR-7标准的文件上传类,以便您在RoadRunner中正确处理文件上传。即使您将项目切换到另一个服务器环境(例如spark serve、Apache、Nginx),这个类仍然可以正常工作,且不需要任何代码修改。
您可以通过控制器(或任何其他位置)中的SDPMlab\Ci4Roadrunner\UploadedFileBridge::getPsr7UploadedFiles()
来获取上传的文件。此方法将返回一个数组,其中包含上传文件对象。该对象的方法与PSR-7 上传文件接口的规定相同。
<?php namespace App\Controllers; use CodeIgniter\API\ResponseTrait; use SDPMlab\Ci4Roadrunner\UploadedFileBridge; class FileUploadTest extends BaseController { use ResponseTrait; protected $format = "json"; /** * form-data */ public function fileUpload() { $files = UploadedFileBridge::getPsr7UploadedFiles(); $data = []; foreach ($files as $file) { $fileNameArr = explode('.', $file->getClientFilename()); $fileEx = array_pop($fileNameArr); $newFileName = uniqid(rand()) . "." . $fileEx; $newFilePath = WRITEPATH . 'uploads' . DIRECTORY_SEPARATOR . $newFileName; $file->moveTo($newFilePath); $data[$file->getClientFilename()] = md5_file($newFilePath); } return $this->respondCreated($data); } /** * form-data multiple upload */ public function fileMultipleUpload() { $files = UploadedFileBridge::getPsr7UploadedFiles()["data"]; $data = []; foreach ($files as $file) { $fileNameArr = explode('.', $file->getClientFilename()); $fileEx = array_pop($fileNameArr); $newFileName = uniqid(rand()) . "." . $fileEx; $newFilePath = WRITEPATH . 'uploads' . DIRECTORY_SEPARATOR . $newFileName; $file->moveTo($newFilePath); $data[$file->getClientFilename()] = md5_file($newFilePath); } return $this->respondCreated($data); } }
处理抛出的错误
如果您在-d
开发模式下遇到了需要确认的一些变量或对象内容,您可以使用全局函数dump()
在程序任何位置将错误抛出到终端。
可用命令
ciroad:init
初始化RoadRunner及其所需文件。
- 使用
$ php spark ciroad:init
RoadRunner服务器命令
有关可用命令,您可以参考RoadRunner 官方文档中的说明。