# 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 附录