## 存在問題
見下篇 `協程上下文解決request` 問題。
## swoole
[swoole文檔](https://wiki.swoole.com/#/start/start_http_server)
本篇講解使用協程 `http` 方式,參考了下[hyperf/src/server/src/Server.php](https://github.com/hyperf/hyperf/blob/master/src/server/src/Server.php)。
## 使用函數
不使用 [服務器端 (協程風格) HTTP 服務器](https://wiki.swoole.com/#/coroutine/http_server)
使用 [服務器端 (異步風格) HTTP 服務器](https://wiki.swoole.com/#/http_server)
因為[服務器端 (協程風格) HTTP 服務器](https://wiki.swoole.com/#/coroutine/http_server)設置[pid_file](https://wiki.swoole.com/#/server/setting?id=pid_file)是沒用的。
用`異步風格` 也可以用協程: [enable_coroutine](https://wiki.swoole.com/#/server/setting?id=enable_coroutine)
## 創建swoole.php
```
<?php
use core\request\PhpRequest;
error_reporting(E_ALL);
ini_set("display_errors","On");
require_once __DIR__ . '/vendor/autoload.php'; // 引入自動加載
require_once __DIR__ . '/app.php'; // 框架的文件
$start = function()
{
Swoole\Runtime::enableCoroutine($flags = SWOOLE_HOOK_ALL);
// 如果你用了CURL PDO之類的客戶端 請開啟這個客戶端協程化
// 詳細見文檔: https://wiki.swoole.com/#/runtime
// 綁定主機 端口
$http = new Swoole\Http\Server('0.0.0.0', 9501);
$http->set([
// 進程pid文件
'pid_file' => FRAME_BASE_PATH.'/storage/swoole.pid',
'enable_coroutine' => true, // 開啟異步協程化 默認開啟
'worker_num' => 4 // Worker進程數 跟協程處理有關系 https://wiki.swoole.com/#/server/setting?id=worker_num
]);
$http->on('request', function ($request, $response) {
echo Swoole\Coroutine::getCid().PHP_EOL; // 打印當前協程id
// 文檔:https://wiki.swoole.com/#/coroutine/coroutine?id=getcid
// 綁定request 現在這個是有問題 因為容器的單例的 所以request會一直變
(數據錯亂)
// 應該使用協程上下文來保存request 下一篇文章會講
$server = $request->server;
app()->bind(\core\request\RequestInterface::class,function () use ($server){
return PhpRequest::create(
$server['path_info'],
$server['request_method'],
$server
);
},false);
$response->end(
app('response')->setContent( // 響應
app('router')->dispatch( // 路由
app(\core\request\RequestInterface::class) // 請求
)
)->getContent()
);
});
echo 'start ok'.PHP_EOL;
$http->start();
};
$stop = function ()
{
if(! file_exists(FRAME_BASE_PATH.'/storage/swoole.pid'))
return;
$pid = file_get_contents(FRAME_BASE_PATH.'/storage/swoole.pid');
Swoole\Process::kill($pid); // 見文檔
};
$handle = $argv[1];
// 啟動
if( $handle == 'start')
$start();
// 停止
elseif( $handle == 'stop');
$stop();
```
## 運行
```
php swoole.php start
```



## 關于協程id重復解釋
### 使用ab測試

```
ab -n 8 -c 8 http://127.0.0.1:9501/
```
### 結果

`echo Swoole\Coroutine::getCid().PHP_EOL; // 打印當前協程id
`
這里打印了 `協程id`, 你會發現 `協程id` 重復了。
不用擔心, `協程id` 這是唯一的,。
是因為設置了 `'worker_num' => 4`。
- 前言
- 基礎篇
- 1. 第一步 創建框架目錄結構
- 2. 引入composer自動加載
- 3. php自動加載 (解釋篇)
- 4. 創建容器 注冊樹模式
- 5. 關于psr規范解釋
- 6. 關于"容器" "契約" "依賴注入" (解釋篇)
- 7. 添加函數文件helpers.php
- 8. 初始化請求(Request)
- 9. 響應 (Response)
- 10. 路由一 (路由組實現)
- 11. 路由二 (加入中間件)
- 12. 配置信息 (類似laravel)
- 13. 數據庫連接 (多例模式)
- 14. 查詢構造器 (query builder)
- MVC實現
- M 模型實現 (數據映射 + 原型 模式)
- C 控制器實現 + 控制器中間件
- V 視圖實現 (Laravel Blade 引擎)
- V 視圖切換成 ThinkPhp 模板 引擎)
- 其他輪子
- 日志
- 自定義異常 (異常托管)
- 單元測試 (phpunit)
- 替換成swoole的http服務器
- 協程上下文解決request問題
- qps測試
- 發布到packagist.org