├── .github └── workflows │ └── test-phpunit.yml ├── .gitignore ├── .php-cs-fixer.dist.php ├── README.md ├── README_zh-TW.md ├── build └── .gitkeep ├── composer.json ├── dev ├── .gitignore ├── LICENSE ├── README.md ├── README_ZH-TW.md ├── app │ ├── .htaccess │ ├── Common.php │ ├── Config │ │ ├── App.php │ │ ├── Autoload.php │ │ ├── Boot │ │ │ ├── development.php │ │ │ ├── production.php │ │ │ └── testing.php │ │ ├── CURLRequest.php │ │ ├── Cache.php │ │ ├── Constants.php │ │ ├── ContentSecurityPolicy.php │ │ ├── Cookie.php │ │ ├── Database.php │ │ ├── DocTypes.php │ │ ├── Email.php │ │ ├── Encryption.php │ │ ├── Events.php │ │ ├── Exceptions.php │ │ ├── Feature.php │ │ ├── Filters.php │ │ ├── ForeignCharacters.php │ │ ├── Format.php │ │ ├── Generators.php │ │ ├── Honeypot.php │ │ ├── Images.php │ │ ├── Kint.php │ │ ├── Logger.php │ │ ├── Migrations.php │ │ ├── Mimes.php │ │ ├── Modules.php │ │ ├── Pager.php │ │ ├── Paths.php │ │ ├── Publisher.php │ │ ├── Routes.php │ │ ├── Security.php │ │ ├── Services.php │ │ ├── Toolbar.php │ │ ├── UserAgents.php │ │ ├── Validation.php │ │ └── View.php │ ├── Controllers │ │ ├── BaseController.php │ │ ├── BasicTest.php │ │ ├── FileUploadTest.php │ │ ├── Home.php │ │ ├── SessionTest.php │ │ └── TestRest.php │ ├── Database │ │ ├── Migrations │ │ │ └── .gitkeep │ │ └── Seeds │ │ │ └── .gitkeep │ ├── Filters │ │ └── .gitkeep │ ├── Helpers │ │ └── .gitkeep │ ├── Language │ │ ├── .gitkeep │ │ └── en │ │ │ └── Validation.php │ ├── Libraries │ │ └── .gitkeep │ ├── Models │ │ └── .gitkeep │ ├── ThirdParty │ │ └── .gitkeep │ ├── Views │ │ ├── errors │ │ │ ├── cli │ │ │ │ ├── error_404.php │ │ │ │ ├── error_exception.php │ │ │ │ └── production.php │ │ │ └── html │ │ │ │ ├── debug.css │ │ │ │ ├── debug.js │ │ │ │ ├── error_404.php │ │ │ │ ├── error_exception.php │ │ │ │ └── production.php │ │ └── welcome_message.php │ └── index.html ├── builds ├── composer.json ├── composer.lock ├── env ├── phpunit.xml.dist ├── public │ ├── .htaccess │ ├── favicon.ico │ ├── index.php │ └── robots.txt ├── spark ├── tests │ ├── README.md │ ├── _support │ │ ├── Database │ │ │ ├── Migrations │ │ │ │ └── 2020-02-22-222222_example_migration.php │ │ │ └── Seeds │ │ │ │ └── ExampleSeeder.php │ │ ├── Libraries │ │ │ └── ConfigReader.php │ │ └── Models │ │ │ └── ExampleModel.php │ ├── bootstrap.php │ └── codeigniter4Roadrunner │ │ ├── RequestBridgeTest.php │ │ ├── UploadedFileBridgeTest.php │ │ └── httpTest │ │ ├── BasicTest.php │ │ ├── FileUploadTest.php │ │ ├── RestTest.php │ │ ├── SessionTest.php │ │ └── testFiles │ │ ├── upload1.text │ │ └── upload2.text └── writable │ ├── .htaccess │ ├── cache │ └── index.html │ ├── logs │ └── index.html │ ├── session │ └── index.html │ └── uploads │ └── index.html ├── rector.php └── src ├── Commands ├── InitLibrary.php └── file │ ├── .rr.yaml │ └── psr-worker.php ├── Debug ├── Exceptions.php └── Toolbar.php ├── HandleDBConnection.php ├── RequestHandler.php ├── ResponseBridge.php ├── UploadedFile.php ├── UploadedFileBridge.php └── UriBridge.php /.github/workflows/test-phpunit.yml: -------------------------------------------------------------------------------- 1 | name: PHPUnit 2 | 3 | on: 4 | push: 5 | branches: 6 | - dev 7 | paths: 8 | - 'src/**' 9 | - 'test/**' 10 | - composer.json 11 | - '**.php' 12 | - .github/workflows/test-phpunit.yml 13 | pull_request: 14 | branches: 15 | - dev 16 | paths: 17 | - 'src/**' 18 | - 'test/**' 19 | - composer.json 20 | - '**.php' 21 | - .github/workflows/test-phpunit.yml 22 | 23 | jobs: 24 | 25 | tests: 26 | runs-on: ubuntu-18.04 27 | if: "!contains(github.event.head_commit.message, '[ci skip]')" 28 | name: PHP ${{ matrix.php-ver }} 29 | 30 | strategy: 31 | fail-fast: false 32 | matrix: 33 | php-ver: ['7.3','7.4'] 34 | 35 | steps: 36 | - name: Checkout 37 | uses: actions/checkout@v2 38 | 39 | - name: Setup PHP, with composer and extensions 40 | run: | 41 | sudo add-apt-repository ppa:ondrej/php -y 42 | sudo apt update -y 43 | sudo apt-get install php${{ matrix.php-ver }} 44 | sudo apt install php-pear php${{ matrix.php-ver }}-curl php${{ matrix.php-ver }}-dev php${{ matrix.php-ver }}-mbstring php${{ matrix.php-ver }}-zip php${{ matrix.php-ver }}-mysql php${{ matrix.php-ver }}-xml php${{ matrix.php-ver }}-fpm php${{ matrix.php-ver }}-intl -y 45 | sudo apt-get update -y 46 | sudo apt-get install -y php-xdebug 47 | sudo curl -s https://getcomposer.org/installer | php 48 | sudo mv composer.phar /usr/local/bin/composer 49 | 50 | - name: Install dependencies 51 | working-directory: ./test 52 | run: | 53 | composer update 54 | env: 55 | COMPOSER_AUTH: ${{ secrets.COMPOSER_AUTH }} 56 | 57 | - name: Init roadrunner server 58 | working-directory: ./test 59 | run: | 60 | sudo ./vendor/bin/rr get 61 | cp ../src/Commands/file/psr-worker.php psr-worker.php 62 | sudo ./rr serve -v -d & 63 | 64 | - name: Test with PHPUnit 65 | working-directory: ./test 66 | run: script -e -c "vendor/bin/phpunit -v" 67 | env: 68 | TERM: xterm-256color -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode 2 | vendor/ 3 | .idea/ 4 | composer.lock 5 | .php-cs-fixer.cache 6 | -------------------------------------------------------------------------------- /.php-cs-fixer.dist.php: -------------------------------------------------------------------------------- 1 | files() 9 | ->in([ 10 | __DIR__ . '/src/', 11 | // __DIR__ . '/tests/', 12 | __DIR__ . '/dev/app/', 13 | __DIR__ . '/dev/tests/', 14 | ]) 15 | ->exclude('build') 16 | ->append([__FILE__]); 17 | 18 | $overrides = []; 19 | 20 | $options = [ 21 | 'finder' => $finder, 22 | 'cacheFile' => 'build/.php-cs-fixer.cache', 23 | ]; 24 | 25 | return Factory::create(new CodeIgniter4(), $overrides, $options)->forProjects(); 26 | -------------------------------------------------------------------------------- /README_zh-TW.md: -------------------------------------------------------------------------------- 1 | # Codeigniter4-Roadrunner 2 | 3 |

4 | logo 5 |

6 | 7 | [![Latest Stable Version](https://poser.pugx.org/sdpmlab/codeigniter4-roadrunner/v)](//packagist.org/packages/sdpmlab/codeigniter4-roadrunner) [![Total Downloads](https://poser.pugx.org/sdpmlab/codeigniter4-roadrunner/downloads)](//packagist.org/packages/sdpmlab/codeigniter4-roadrunner) [![Latest Unstable Version](https://poser.pugx.org/sdpmlab/codeigniter4-roadrunner/v/unstable)](//packagist.org/packages/sdpmlab/codeigniter4-roadrunner) [![License](https://poser.pugx.org/sdpmlab/codeigniter4-roadrunner/license)](//packagist.org/packages/sdpmlab/codeigniter4-roadrunner) 8 | 9 | Codeigniter4-RoadRunner 提供的是 Roadrunner-Worker 與 Codeigniter4 在 Request 與 Response 物件上的同步,因為 Codeigniter4 並沒有完整實作 [PSR-7 規範](https://codeigniter.tw/user_guide/intro/psr.html)。所以你需要使用這個程式庫才能讓你的 Codeigniter4 專案透過 RoadRunner Server 運作。 10 | 11 | ## 安裝 12 | 13 | ### 需求 14 | 1. CodeIgniter Framework 4.2.0 以上 15 | 2. Composer 16 | 3. 安裝並開啟 php-curl 擴充套件 17 | 4. 安裝並開啟 php-zip 擴充套件 18 | 5. 安裝並開啟 php-sockets 擴充套件 19 | 20 | ### Composer 安裝 21 | 22 | 於專案根目錄下,使用 Composer 下載程式庫與其所需之依賴。 23 | 24 | ``` 25 | composer require sdpmlab/codeigniter4-roadrunner 26 | ``` 27 | 28 | 使用程式庫提供的內建指令初始化 Roadrunner 與其所需的檔案。 29 | 30 | ``` 31 | php spark ciroad:init 32 | ``` 33 | 34 | ## 運作伺服器 35 | 36 | 你可以選擇使用不同的指令在專案根目錄中運作 RoadRunner Server: 37 | 38 | 1. 在 Windows-cmd 中直使用 RoadRunner 指令 39 | ``` 40 | rr.exe serve -d 41 | ``` 42 | 3. 在 MacOS/Linux 中直接使用 RoadRunner 指令 43 | ``` 44 | ./rr serve -d 45 | ``` 46 | 47 | ## 伺服器組態設定 48 | 49 | 伺服器組態設定應置於專案根目錄下,並命名為 `.rr.yaml` 。程式庫初始化後產出的預設檔案看起來會像這樣子: 50 | 51 | ```yaml 52 | version: "2.7" 53 | rpc: 54 | listen: tcp://127.0.0.1:6001 55 | 56 | server: 57 | command: "php psr-worker.php" 58 | # env: 59 | # XDEBUG_SESSION: 1 60 | 61 | http: 62 | address: "0.0.0.0:8080" 63 | static: 64 | dir: "./public" 65 | forbid: [".htaccess", ".php"] 66 | pool: 67 | num_workers: 1 68 | # max_jobs: 64 69 | # debug: true 70 | 71 | # reload: 72 | # interval: 1s 73 | # patterns: [ ".php" ] 74 | # services: 75 | # http: 76 | # recursive: true 77 | # ignore: [ "vendor" ] 78 | # patterns: [ ".php", ".go", ".md" ] 79 | # dirs: [ "." ] 80 | ``` 81 | 82 | 當然,你可以參考 [Roadrunner 手冊](https://roadrunner.dev/docs/intro-config) 建立符合專案需求的組態設定檔。 83 | 84 | ## 開發建議 85 | 86 | ### 自動重新載入 87 | 88 | RoadRunner 預設的情況下,必須在每次修改 php 檔案後重啟伺服器,你所做的修改才會生效,這在開發上似乎不那麼友善。 89 | 90 | 你可以修改你的 `.rr.yaml` 組態設定檔案,加入以下設定後以 `-d` 開發模式啟動 RoadRunner Server,它將會自動偵測 PHP 檔案是否修改,並即時重新載入 Worker 。 91 | 92 | ```yaml 93 | reload: 94 | interval: 1s 95 | patterns: [ ".php" ] 96 | services: 97 | http: 98 | recursive: true 99 | ignore: [ "vendor" ] 100 | patterns: [ ".php", ".go", ".md" ] 101 | dirs: [ "." ] 102 | ``` 103 | 104 | `reload` 是非常耗費資源的,請不要在正式環境中打開這個選項。 105 | 106 | ### 使用 Codeigniter4 Request 與 Response 物件 107 | 108 | Codeigniter4 並沒有實作完整的 [HTTP message 介面](https://www.php-fig.org/psr/psr-7/),所以這個程式庫著重於 `PSR-7 介面` 與 `Codeigniter4 HTTP 介面` 的同步。 109 | 110 | 基於上述原因,在開發上,你應該使用 Codeigniter4 所提供的 `$this->request` 或是使用全域函數 `\Config\Services::('request')` 取得正確的 request 物件;使用 `$this->response` 或是 `\Config\Services::('response')` 取得正確的 response 物件。 111 | 112 | 請注意,在建構給予使用者的響應時,不論是 `header` 或 `set-cookies` 應該避免使用 PHP 內建的方法進行設定。而是使用 [Codeigniter4 響應物件](https://codeigniter.tw/user_guide/outgoing/response.html) 提供的 `setHeader()` 與 `setCookie()` 進行設定。 113 | 114 | ### 以 return 結束控制器邏輯 115 | 116 | 在 Controller 中,盡量使用 return 結束程式邏輯,不論是視圖的響應或是 API 響應,減少使用 `echo` 輸出內容可以避免很多錯誤,就像這個樣子。 117 | 118 | ```php 119 | response->setHeader("X-Set-Auth-Token",uniqid()); 140 | return $this->respond(["status"=>true]); 141 | } 142 | 143 | } 144 | ``` 145 | 146 | ### 使用內建 Session 程式庫 147 | 148 | 我們只針對 Codeigniter4 內建 [Session 程式庫](https://codeigniter.tw/user_guide/libraries/sessions.html) 進行支援,並不保證使用 `session_start()` 與 `$_SESSION` 是否能照常運作。所以,你應該避免使用 PHP 內建的 Session 方法,而是以 Codeigniter4 框架內建的程式庫為主。 149 | 150 | ### 在只有一個 Worker 的環境中開發與除錯 151 | 152 | 因為 RoadRunner 與其他伺服器軟體(Nginx、Apache)有著根本上的不同,每個 Codeigniter4 將會以 Worker 的形式持久化於記憶體中,HTTP 的請求會重複利用到這些 Worker 進行處裡。所以,我們最好在只有單個 Worker 的情況下開發軟體並測試是否穩定,以證明在多個 Woker 的實際環境中能正常運作。 153 | 154 | 你可以參考以下 `.rr.yaml` 設定將 Worker 的數量降到最低: 155 | 156 | ```yaml 157 | http: 158 | address: "0.0.0.0:8080" 159 | static: 160 | dir: "./public" 161 | forbid: [".htaccess", ".php"] 162 | pool: 163 | num_workers: 1 164 | # max_jobs: 64 165 | # debug: true 166 | ``` 167 | 168 | ### 資料庫連線 169 | 170 | 我們只針對 Codeigniter4 內建 [Database 程式庫](https://codeigniter.tw/user_guide/database/index.html) 進行支援,並不保證 PHP 內建的方法是否能照常運作。所以,你應該避免使用內建的 PHP 資料庫連線方法,而是以 Codeigniter4 框架內建的程式庫為主。 171 | 172 | 預設的情況下,在 Worker 中的 DB 連線是持久的,並會在連線失效時自動重新連線。所有進入 Worker 的 Request 都使用同一個 DB 連線實體。如果你不想要這個預設設定,希望每個進入 Worker 的 Request 都使用重新連線的 DB 連線實體。你可以在專案根目錄下的 `.env` 檔案加入以下設定。 173 | 174 | ```env 175 | CIROAD_DB_AUTOCLOSE = true 176 | ``` 177 | 178 | ## 全域方法 179 | 180 | 我們提供了一些全域方法,幫助你更加順利地開發你的專案。 181 | 182 | ### 處裡檔案上傳 183 | 184 | 因為 RoadRunner Worker 無法傳遞正確的 `$_FILES` 內容,所以 Codeingiter4 的 [檔案上傳類別](https://codeigniter.tw/user_guide/libraries/uploaded_files.html) 將無法正確運作。對此,我們提供了符合 PSR-7 規範的檔案上傳類別,讓你可以正確地在 RoadRunner 中處理檔案上傳。就算你將專案切換到了其他伺服器環境(spark serve、Apache、Nginx)運作,這個類別依舊可以正常使用,並且不需要修改任何程式碼。 185 | 186 | 你可以在控制器(或任何地方),以 `SDPMlab\Ci4Roadrunner\UploadedFileBridge::getPsr7UploadedFiles()` 取得使用者上傳的檔案。這個方法將回傳以 Uploaded File 物件組成的陣列。此物件可用的方法與 [PSR-7 Uploaded File Interface](https://www.php-fig.org/psr/psr-7/#36-psrhttpmessageuploadedfileinterface) 中規範的一樣。 187 | 188 | ```php 189 | getClientFilename()); 211 | $fileEx = array_pop($fileNameArr); 212 | $newFileName = uniqid(rand()) . "." . $fileEx; 213 | $newFilePath = WRITEPATH . 'uploads' . DIRECTORY_SEPARATOR . $newFileName; 214 | $file->moveTo($newFilePath); 215 | $data[$file->getClientFilename()] = md5_file($newFilePath); 216 | } 217 | return $this->respondCreated($data); 218 | } 219 | 220 | /** 221 | * form-data multiple upload 222 | */ 223 | public function fileMultipleUpload() 224 | { 225 | $files = UploadedFileBridge::getPsr7UploadedFiles()["data"]; 226 | $data = []; 227 | foreach ($files as $file) { 228 | $fileNameArr = explode('.', $file->getClientFilename()); 229 | $fileEx = array_pop($fileNameArr); 230 | $newFileName = uniqid(rand()) . "." . $fileEx; 231 | $newFilePath = WRITEPATH . 'uploads' . DIRECTORY_SEPARATOR . $newFileName; 232 | $file->moveTo($newFilePath); 233 | $data[$file->getClientFilename()] = md5_file($newFilePath); 234 | } 235 | return $this->respondCreated($data); 236 | } 237 | } 238 | ``` 239 | 240 | ### 處理錯誤拋出 241 | 242 | 如果你在 `-d` 開發模式中碰到了一些需要確認的變數、或物件內容,無論在程式的何處,你都可以使用全域函數 `dump()` 來將錯誤拋出到終端機上。 243 | 244 | ## 可用指令 245 | 246 | ### ciroad:init 247 | 248 | 初始化 Roadrunner 與其所需的檔案。 249 | 250 | * Use 251 | ``` 252 | $ php spark ciroad:init 253 | ``` 254 | 255 | ### RoadRunner Server Commands 256 | 257 | 關於可以用的指令,你可以參考 RoadRunner [官方文件](https://roadrunner.dev/docs/beep-beep-cli) 的說明。 -------------------------------------------------------------------------------- /build/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SDPM-lab/Codeigniter4-Roadrunner/9d108012128e6ef150247a6608dd06960c4fd0dd/build/.gitkeep -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "sdpmlab/codeigniter4-roadrunner", 3 | "description": "Make Codeigniter4 work on Roadrunner Server.", 4 | "keywords": [ 5 | "codeigniter", 6 | "codeigniter4", 7 | "Roadrunner" 8 | ], 9 | "type": "library", 10 | "license": "MIT", 11 | "authors": [ 12 | { 13 | "name": "MonkenWu", 14 | "homepage": "https://github.com/monkenWu" 15 | }, 16 | { 17 | "name": "SDPM-lab", 18 | "homepage": "https://github.com/SDPM-lab" 19 | } 20 | ], 21 | "minimum-stability": "dev", 22 | "prefer-stable": true, 23 | "require": { 24 | "php" : "^7.4 || ^8.0", 25 | "codeigniter4/framework": "^4.2.0", 26 | "spiral/roadrunner": "^2", 27 | "spiral/dumper": "^2.8", 28 | "laminas/laminas-diactoros": "^2.8", 29 | "nyholm/psr7": "^1.4" 30 | }, 31 | "autoload": { 32 | "psr-4": { 33 | "SDPMlab\\Ci4Roadrunner\\": "src/" 34 | } 35 | }, 36 | "require-dev": { 37 | "codeigniter4/devkit": "^1.0", 38 | "rector/rector": "0.12.16" 39 | }, 40 | "config": { 41 | "allow-plugins": { 42 | "phpstan/extension-installer": true, 43 | "composer/package-versions-deprecated": true 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /dev/.gitignore: -------------------------------------------------------------------------------- 1 | #------------------------- 2 | # Operating Specific Junk Files 3 | #------------------------- 4 | 5 | # OS X 6 | .DS_Store 7 | .AppleDouble 8 | .LSOverride 9 | 10 | # OS X Thumbnails 11 | ._* 12 | 13 | # Windows image file caches 14 | Thumbs.db 15 | ehthumbs.db 16 | Desktop.ini 17 | 18 | # Recycle Bin used on file shares 19 | $RECYCLE.BIN/ 20 | 21 | # Windows Installer files 22 | *.cab 23 | *.msi 24 | *.msm 25 | *.msp 26 | 27 | # Windows shortcuts 28 | *.lnk 29 | 30 | # Linux 31 | *~ 32 | 33 | # KDE directory preferences 34 | .directory 35 | 36 | # Linux trash folder which might appear on any partition or disk 37 | .Trash-* 38 | 39 | #------------------------- 40 | # Environment Files 41 | #------------------------- 42 | # These should never be under version control, 43 | # as it poses a security risk. 44 | .env 45 | .vagrant 46 | Vagrantfile 47 | 48 | #------------------------- 49 | # Temporary Files 50 | #------------------------- 51 | writable/cache/* 52 | !writable/cache/index.html 53 | 54 | writable/logs/* 55 | !writable/logs/index.html 56 | 57 | writable/session/* 58 | !writable/session/index.html 59 | 60 | writable/uploads/* 61 | !writable/uploads/index.html 62 | 63 | writable/debugbar/* 64 | 65 | php_errors.log 66 | 67 | #------------------------- 68 | # User Guide Temp Files 69 | #------------------------- 70 | user_guide_src/build/* 71 | user_guide_src/cilexer/build/* 72 | user_guide_src/cilexer/dist/* 73 | user_guide_src/cilexer/pycilexer.egg-info/* 74 | 75 | #------------------------- 76 | # Test Files 77 | #------------------------- 78 | tests/coverage* 79 | 80 | # Don't save phpunit under version control. 81 | phpunit 82 | 83 | #------------------------- 84 | # Composer 85 | #------------------------- 86 | vendor/ 87 | 88 | #------------------------- 89 | # IDE / Development Files 90 | #------------------------- 91 | 92 | # Modules Testing 93 | _modules/* 94 | 95 | # phpenv local config 96 | .php-version 97 | 98 | # Jetbrains editors (PHPStorm, etc) 99 | .idea/ 100 | *.iml 101 | 102 | # Netbeans 103 | nbproject/ 104 | build/ 105 | nbbuild/ 106 | dist/ 107 | nbdist/ 108 | nbactions.xml 109 | nb-configuration.xml 110 | .nb-gradle/ 111 | 112 | # Sublime Text 113 | *.tmlanguage.cache 114 | *.tmPreferences.cache 115 | *.stTheme.cache 116 | *.sublime-workspace 117 | *.sublime-project 118 | .phpintel 119 | /api/ 120 | 121 | # Visual Studio Code 122 | .vscode/ 123 | 124 | /results/ 125 | /phpunit*.xml 126 | /.phpunit.*.cache 127 | 128 | rr 129 | rr.exe 130 | .rr.yaml 131 | psr-worker.php 132 | -------------------------------------------------------------------------------- /dev/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014-2019 British Columbia Institute of Technology 4 | Copyright (c) 2019-2021 CodeIgniter Foundation 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /dev/README.md: -------------------------------------------------------------------------------- 1 | # Test Case 2 | 3 | This is the Codeigniter4-RoadRunner test case project, it is built by Codeigniter4, and has loaded the Codeigniter4-Roadrunner library class inside the upper directory included in the `src` in. 4 | 5 | You can run the test right after you modified the Codeigniter4-Roadrunner project files, verify if the functions are complete; Or write some related program logic in this project to assist your development. 6 | 7 | ## Test Range 8 | 9 | This test case takes the actual sent CURL Request as test approach, because what Codeigniter4-Roadrunner provide is the synchronization on HTTP Request and Response objects of Roadrunner-Worker and Codeigniter4 (Since Codeigniter4 doesn't implement PSR-7 interface standard). In other words, we just have to verify if the server workes as what we wanted under the actual HTTP connection. 10 | 11 | 1. BasicTest:Test HTTP `GET`、`POST`、`query`、`form-data`, and the `php echo` output command, and if `header` can process normally and give us outputs. 12 | 2. FileUploadTest:Test if file upload class can work correctly and move files. 13 | 3. RestTest:Test if Codeigniter4 RESTful library can work properly and can parse every verbs 14 | 4. SessionTest:Test if the Session mode, triggered by the file system can work properly. 15 | 16 | ## Requirements 17 | 18 | We recommend you to use the latest PHPUnit. While we're writing scripts, the version we're running at is version `9.5.19`. You might need to use Composer to download the library your project needed back to your develop environment. 19 | 20 | ``` 21 | composer install 22 | ``` 23 | 24 | Next, you must initialize the environment that Roadrunner needed. 25 | 26 | ``` 27 | php spark ciroad:init 28 | ``` 29 | 30 | Finally, please confirm if the directory has these three files including `rr` (if you are developing under Windows, you will see `rr.exe`), `.rr.yaml`, `psr-worker.php`. 31 | 32 | ## Run Tests 33 | 34 | Before running tests, please open `.rr.yaml` file first, and ensure this configuration file has these settings: 35 | 36 | ```yaml 37 | rpc: 38 | listen: tcp://127.0.0.1:6001 39 | 40 | server: 41 | command: "php psr-worker.php" 42 | 43 | http: 44 | address: "0.0.0.0:8080" 45 | static: 46 | dir: "./public" 47 | forbid: [".htaccess", ".php"] 48 | pool: 49 | num_workers: 1 50 | ``` 51 | 52 | Since Roadrunner-Worker lasts inside RAMs, HTTP requests will reuse Workers to process. Hence, we need to test the stability under the environment with only one worker to prove that it can work properly under several workers. 53 | 54 | Next, you have to open a terminal and cd to the root directory, type the commands below to run the Roadrunner server: 55 | 56 | ``` 57 | ./rr serve -d 58 | ``` 59 | 60 | Finally, open another new terminal and cd to the test project, type the commands below to run tests: 61 | 62 | ``` 63 | ./vendor/bin/phpunit 64 | ``` 65 | 66 | If you're running tests under Windows CMD, your command should be like this: 67 | 68 | ``` 69 | vendor\bin\phpunit 70 | ``` 71 | -------------------------------------------------------------------------------- /dev/README_ZH-TW.md: -------------------------------------------------------------------------------- 1 | # 運作系統測試 2 | 3 | 這是 Codeigniter4-Roadrunner 的測試案例專案,它以 Codeigniter4 建置,並在 `app/config/Autoload.php` 中,載入了上層目錄的 `src` 中包含的 Codeigniter4-Roadrunner 程式庫類別。 4 | 5 | 你可以在修改 Codeigniter4-Roadrunner 專案檔案後立即運作這個測試,驗證功能是否完備;或是在這個專案中撰寫相關的程式邏輯,輔助你的開發。 6 | 7 | ## 測試範圍 8 | 9 | 本測試案例專案以發送實際的 CURL Request 為測試方法,因為 Codeigniter4-Roadrunner 提供的是 Roadrunner-Worker 與 Codeigniter4 在 HTTP Request 與 Response 物件上的同步(因為 Codeigniter4 並沒有實作 PSR-7 介面規範)。也就是說,我們只需要驗證在實際的 HTTP 連線下,伺服器是否依照我們所想的方式工作。 10 | 11 | 1. BasicTest:測試 HTTP `GET`、`POST`、`query`、`form-data`,與畫面輸出、 `php echo` 指令,以及 `header` 是否能夠正常處理與輸出。 12 | 2. FileUploadTest:測試檔案上傳類別是否正確運作與移動檔案。 13 | 3. RestTest:測試 Codeigniter4 RESTful 程式庫是否能夠正確運作與解析各式動詞。 14 | 4. SessionTest:測試檔案系統驅動的 Session 模式是否能夠正常運作。 15 | 16 | ## 要求 17 | 18 | 建議使用最新版本的 PHPUnit。在撰寫本文時,我們正在運作的是版本 `9.5.19` 。你可能需要先使用 Composer 將專案所需的程式庫下載回你的開發環境。 19 | 20 | ``` 21 | composer install 22 | ``` 23 | 24 | 接著,你必須初始化 Roadrunner 伺服器所需要的環境。 25 | 26 | ``` 27 | php spark ciroad:init 28 | ``` 29 | 30 | 最後,請確定目錄下包含 `rr`(若你是 windows 環境則是 `rr.exe`)、`.rr.yaml` 、`psr-worker.php` 這三個檔案。 31 | 32 | ## 運作測試 33 | 34 | 在運作測試前,請先打開 `.rr.yaml` 檔案,並確保這個設定檔案具有以下設定: 35 | 36 | ```yaml 37 | rpc: 38 | listen: tcp://127.0.0.1:6001 39 | 40 | server: 41 | command: "php psr-worker.php" 42 | 43 | http: 44 | address: "0.0.0.0:8080" 45 | static: 46 | dir: "./public" 47 | forbid: [".htaccess", ".php"] 48 | pool: 49 | num_workers: 1 50 | ``` 51 | 52 | 因為 Roadrunner-Worker 持久化於記憶體中,HTTP 的請求會重複利用到這些 Worker 進行處裡。所以我們必須要在只有單個 Worker 的情況下測試是否穩定,以證明在多個 Woker 的實際環境中能正常運作。 53 | 54 | 接著,你得先打開一個終端機,移動到測試專案的根目錄下,輸入以下指令運作起 Roadrunner 伺服器: 55 | 56 | ``` 57 | rr serve -d 58 | ``` 59 | 60 | 最後,再打開一個新的終端機,移動到測試專案下,輸入以下指令運作測試: 61 | 62 | ``` 63 | ./vendor/bin/phpunit 64 | ``` 65 | 66 | 如果你以 Windows 的 CMD 運作測試的話,你的指令會是這樣: 67 | 68 | ``` 69 | vendor\bin\phpunit 70 | ``` -------------------------------------------------------------------------------- /dev/app/.htaccess: -------------------------------------------------------------------------------- 1 | 2 | Require all denied 3 | 4 | 5 | Deny from all 6 | 7 | -------------------------------------------------------------------------------- /dev/app/Common.php: -------------------------------------------------------------------------------- 1 | SYSTEMPATH, 37 | * 'App' => APPPATH 38 | * ]; 39 | *``` 40 | * 41 | * @var array 42 | */ 43 | public $psr4 = [ 44 | APP_NAMESPACE => APPPATH, // For custom app namespace 45 | 'Config' => APPPATH . 'Config', 46 | 'SDPMlab\\Ci4Roadrunner\\' => ROOTPATH . '..' . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR, 47 | ]; 48 | 49 | /** 50 | * ------------------------------------------------------------------- 51 | * Class Map 52 | * ------------------------------------------------------------------- 53 | * The class map provides a map of class names and their exact 54 | * location on the drive. Classes loaded in this manner will have 55 | * slightly faster performance because they will not have to be 56 | * searched for within one or more directories as they would if they 57 | * were being autoloaded through a namespace. 58 | * 59 | * Prototype: 60 | *``` 61 | * $classmap = [ 62 | * 'MyClass' => '/path/to/class/file.php' 63 | * ]; 64 | *``` 65 | * 66 | * @var array 67 | */ 68 | public $classmap = []; 69 | 70 | /** 71 | * ------------------------------------------------------------------- 72 | * Files 73 | * ------------------------------------------------------------------- 74 | * The files array provides a list of paths to __non-class__ files 75 | * that will be autoloaded. This can be useful for bootstrap operations 76 | * or for loading functions. 77 | * 78 | * Prototype: 79 | * ``` 80 | * $files = [ 81 | * '/path/to/my/file.php', 82 | * ]; 83 | * ``` 84 | * 85 | * @var array 86 | */ 87 | public $files = []; 88 | } 89 | -------------------------------------------------------------------------------- /dev/app/Config/Boot/development.php: -------------------------------------------------------------------------------- 1 | 122 | */ 123 | public $file = [ 124 | 'storePath' => WRITEPATH . 'cache/', 125 | 'mode' => 0640, 126 | ]; 127 | 128 | /** 129 | * ------------------------------------------------------------------------- 130 | * Memcached settings 131 | * ------------------------------------------------------------------------- 132 | * Your Memcached servers can be specified below, if you are using 133 | * the Memcached drivers. 134 | * 135 | * @see https://codeigniter.com/user_guide/libraries/caching.html#memcached 136 | * 137 | * @var array 138 | */ 139 | public $memcached = [ 140 | 'host' => '127.0.0.1', 141 | 'port' => 11211, 142 | 'weight' => 1, 143 | 'raw' => false, 144 | ]; 145 | 146 | /** 147 | * ------------------------------------------------------------------------- 148 | * Redis settings 149 | * ------------------------------------------------------------------------- 150 | * Your Redis server can be specified below, if you are using 151 | * the Redis or Predis drivers. 152 | * 153 | * @var array 154 | */ 155 | public $redis = [ 156 | 'host' => '127.0.0.1', 157 | 'password' => null, 158 | 'port' => 6379, 159 | 'timeout' => 0, 160 | 'database' => 0, 161 | ]; 162 | 163 | /** 164 | * -------------------------------------------------------------------------- 165 | * Available Cache Handlers 166 | * -------------------------------------------------------------------------- 167 | * 168 | * This is an array of cache engine alias' and class names. Only engines 169 | * that are listed here are allowed to be used. 170 | * 171 | * @var array 172 | */ 173 | public $validHandlers = [ 174 | 'dummy' => DummyHandler::class, 175 | 'file' => FileHandler::class, 176 | 'memcached' => MemcachedHandler::class, 177 | 'predis' => PredisHandler::class, 178 | 'redis' => RedisHandler::class, 179 | 'wincache' => WincacheHandler::class, 180 | ]; 181 | } 182 | -------------------------------------------------------------------------------- /dev/app/Config/Constants.php: -------------------------------------------------------------------------------- 1 | ` element. 81 | * 82 | * Will default to self if not overridden 83 | * 84 | * @var string|string[]|null 85 | */ 86 | public $baseURI; 87 | 88 | /** 89 | * Lists the URLs for workers and embedded frame contents 90 | * 91 | * @var string|string[] 92 | */ 93 | public $childSrc = 'self'; 94 | 95 | /** 96 | * Limits the origins that you can connect to (via XHR, 97 | * WebSockets, and EventSource). 98 | * 99 | * @var string|string[] 100 | */ 101 | public $connectSrc = 'self'; 102 | 103 | /** 104 | * Specifies the origins that can serve web fonts. 105 | * 106 | * @var string|string[] 107 | */ 108 | public $fontSrc; 109 | 110 | /** 111 | * Lists valid endpoints for submission from `
` tags. 112 | * 113 | * @var string|string[] 114 | */ 115 | public $formAction = 'self'; 116 | 117 | /** 118 | * Specifies the sources that can embed the current page. 119 | * This directive applies to ``, `