# 4.2 控制器
控制器是MVC的核心,是連接Model和View的橋梁,是程序處理邏輯的起始代碼。
## Controller基類
框架內置控制器基類`\PG\MSF\Controllers\Controller`,任何控制器都應該繼承它,如:
示例代碼:
[./php-msf-demo/app/Controllers/Demo.php](https://github.com/pinguo/php-msf-demo/blob/master/app/Controllers/Demo.php)
```php
<?php
/**
* 示例控制器
*
* @author camera360_server@camera360.com
* @copyright Chengdu pinguo Technology Co.,Ltd.
*/
namespace App\Controllers;
use PG\MSF\Controllers\Controller;
class Demo extends Controller
{
public function actionGetMockIds()
{
$ids = $this->getConfig()->get('params.mock_ids', []);
$this->outputJson($ids);
}
}
```
- $this->getConfig()->get('params.mock_ids', []);
獲取Server運行實例的配置對象,也可以通過數組的形式訪問,比如`$this->getConfig()['params']['mock_ids']`
- $this->outputJson($data)
Controller::outputJson()方法是響應用戶請求并格式化json輸出,`curl http://127.0.0.1:8000/Demo/GetMockIds | jq .`如:
```json
[
"581af00d4b58d59d22e8d7a6",
"581198754b58d54465ef4cad",
"580c7fa44b58d53f43e21c43",
"57ef6aec4b58d50d24e21a2a",
"57ee28ed4b58d52f24e21969",
"57eb6a484b58d50e3d078076",
"57e23b444b58d52f1e6689fc",
"57dfc9fc4b58d5581e668918",
"57de06b74b58d5471e66882f",
"57d8b78f4b58d5311e6686d5"
]
```
## __construct
控制器的構造方法原型:
```php
<?php
/**
* Web Controller控制器基類
*
* @author camera360_server@camera360.com
* @copyright Chengdu pinguo Technology Co.,Ltd.
*/
namespace PG\MSF\Controllers;
use PG\Exception\Errno;
use PG\Exception\ParameterValidationExpandException;
use PG\Exception\PrivilegeException;
use PG\AOP\Wrapper;
use PG\AOP\MI;
use PG\MSF\Base\Core;
use Exception;
use PG\MSF\Coroutine\CException;
/**
* Class Controller
* @package PG\MSF\Controllers
*/
class Controller extends Core
{
// 略...
/**
* Controller constructor.
*
* @param string $controllerName controller標識
* @param string $methodName method名稱
*/
public function __construct($controllerName, $methodName)
{
// 支持自動銷毀成員變量
MI::__supportAutoDestroy(static::class);
$this->requestStartTime = microtime(true);
}
// 略...
}
```
如用戶業務控制器有其他構造邏輯,需要如下調用基類的構造方法:
```php
/**
* Controller constructor.
*
* @param string $controllerName controller標識
* @param string $methodName method名稱
*/
public function __construct($controllerName, $methodName)
{
parent::__construct($controllerName, $methodName);
// 業務邏輯
}
```
## 動作
控制器由動作組成,他是用戶請求的最小單元邏輯。控制器動作前綴為`action`。
這樣訪問:
http://127.0.0.1:8000/Demo/GetMockIds
這樣的URL時,正在執行的控制器動作為: `Demo::actionGetMockIds()`。
## 獲取對象
在控制器的動作中加載模型或者創建對象是常見的需求,php-msf實現了對象池的設計模式,創建任何對象都需要通過調用`$this->getObject($className)`方法如:
- Demo模型
```php
<?php
/**
* Demo模型
*/
namespace App\Models;
use PG\MSF\Models\Model;
class Demo extends Model
{
public $pro1;
public $pro2;
public function __construct($pro1, $pro2)
{
parent::__construct();
$this->pro1 = $pro1;
$this->pro2 = $pro2;
}
public function getMockIds()
{
// 讀取配置后返回
return $this->getConfig()->get('params.mock_ids', []);
}
}
```
如示例所示,`App\Models\Demo`類文件:
[./php-msf-demo/app/Models/Demo.php](https://github.com/pinguo/php-msf-demo/blob/master/app/Models/Demo.php)
- 調用Demo模型方法
```php
<?php
/**
* 示例控制器
*
* @author camera360_server@camera360.com
* @copyright Chengdu pinguo Technology Co.,Ltd.
*/
namespace App\Controllers;
use PG\MSF\Controllers\Controller;
use App\Models\Demo as DemoModel;
class Demo extends Controller
{
// 略
public function actionGetMockFromModel()
{
/**
* @var DemoModel $demoModel
*/
$demoModel = $this->getObject(DemoModel::class, [1, 2]);
$ids = $demoModel->getMockIds();
$this->outputJson($ids);
}
}
```
- 獲取對象時的構造參數
`$this->getObject($className, ['構造參數1', '構造參數2', ...]);`
第二個參數為構造參數列表,即數組,它會一一映射到類的構造方法。
## 命令行模式
除了處理web請求的Controller,框架還支持命令行模式,需要繼承`\PG\MSF\Console\Controller`,如:
```php
<?php
namespace App\Console;
use PG\MSF\Console\Controller;
class Batch extends Controller
{
public function actionRun()
{
echo '命令行示例';
}
}
```
```bash
>console.php Batch/Run
令行示例
```
示例代碼:
[./php-msf-demo/app/Console/Batch.php](https://github.com/pinguo/php-msf-demo/blob/master/app/Console/Batch.php)
和其他處理web請求的controller一樣,命令行模式也支持協程。
## 其他特性
- 訪問請求上下文
$this->getContext()
- 獲取請求的輸入對象
$this->getContext()->getInput()
- 獲取請求的響應對象
$this->getContext()->getOutput()
- 獲取對象池并獲取一個業務對象
$this->getContext()->getObjectPool()->get(Class::Name)
- 獲取Redis連接池
$this->getRedisPool($poolName)
- 獲取Redis代理
$this->getRedisProxy($proxyName)
- 獲取MySQL連接池
$this->getMysqlPool($poolName)
- 響應json數據格式
$this->outputJson($data, $status)
- 響應視圖
$this->outputView($data, $view)
- 0 文檔說明
- 1 為什么研發新框架
- 1.1 傳統php-fpm工作模式的問題
- 1.2 壓測數據對比
- 1.3 小結
- 2 微服務框架研發概覽
- 2.1 通信框架技術選型
- 2.2 swoole
- 2.3 協程原理
- 2.4 異步、并發
- 2.5 小結
- 3 框架運行環境
- 3.1 環境變量
- 3.2 運行代碼
- 3.3 docker
- 3.4 小結
- 4 框架結構
- 4.1 結構概述
- 4.2 控制器
- 4.3 模型
- 4.4 視圖
- 4.5 同步任務
- 4.6 配置
- 4.7 路由
- 4.8 小結
- 5 框架組件
- 5.1 協程
- 5.2 類的加載
- 5.3 異步Http Client
- 5.4 請求上下文
- 5.5 連接池
- 5.6 對象池
- 5.7 RPC
- 5.8 公共庫
- 5.9 RESTful
- 5.10 多語言
- 5.11 雜項
- 5.12 小結
- 6 常見問題
- 7 附錄