原文发表于:Phalcon入门教程之控制器
控制器在MVC分层中的主要作用是处理请求与响应。Phalcon中的控制器类必须以“ Controller ”为后缀,action则以“ Action ”为后缀。
“ Phalcon\Mvc\Controller
”是Phalcon中控制器的基类,我们写的控制器类通过继承此基类,可以调用在DI中注册的各种服务。一个简单的控制器类示例如下:
namespace Marser\App\Frontend\Controllers;
use Phalcon\Mvc\Controller;
class IndexController extends Controller {
public function indexAction(){
echo 'front index';
exit();
}
}
在浏览器中访问 http://localhost/index/index
即可看到打印结果。
初始化
initialize()函数
Phalcon\Mvc\Controller
中提供了初始化函数 initialize()
,它是最先执行的,并且会优先于任何控制器的其他action:
public function initialize() {
echo 'initialize';
}
有朋友可能会问,为什么不是 __construct()
函数?
onConstruct()函数
其实在 Phalcon\Mvc\Controller
控制器基类中,__construct()
函数已经被声明为 final
,明确禁止子类重写此函数(参考:http://www.iphalcon.cn/api/Phalcon_Mvc_Controller.html ) 。同时, Phalcon\Mvc\Controller
中提供了另一个方法 onConstruct()
来执行初始化的逻辑:
public function onConstruct(){
var_dump('onConstruct');
}
那么, initialize()
和 onConstruct()
的区别是什么?执行顺序又是怎样的?
initialize()和onConstruct()对比
我们进行如下测试:
public function initialize() {
var_dump('initialize');
echo '<pre>';
print_r($this);
}
public function onConstruct(){
var_dump('onConstruct');
echo '<pre>';
print_r($this);
}
public function indexAction(){
echo 'front index';
exit();
}
在浏览器中访问 http://localhost/index/index
可以看到执行顺序是先 onConstruct()
函数,后 initialize()
函数。同时也通过打印当前对象 $this
,看出这两个函数的区别之处:
-
onConstruct()
是实例化对象的过程,相当于 new -
initialize()
是初始化资源的过程。如加载DI中注册的所有服务
接收请求数据
控制器中可通过如下方式接收浏览器发送过来的数据:
public function test1Action(){
$a = $this->request->get('a');
$b = $this->request->getQuery('b');
var_dump("a:{$a}");
var_dump("b:{$b}");
exit;
}
在浏览器中访问 http://localhost/index/test1?a=1&b=2
即可看到打印结果。这里需要注意的是:$this->request->get()
方法能同时获取 GET
和 POST
请求的数据;$this->request->getQuery()
只能获取 GET
方式的请求数据;$this->request->getPost()
只能获取 POST
方式的请求数据。
若想要URL更加的优雅,我们可以尝试使用如下方式来接收URL参数:
public function test2Action($a, $b='bb'){
var_dump("a:{$a}");
var_dump("b:{$b}");
exit;
}
在浏览器中访问以下两种方式的URL,看看打印结果是什么? :) http://localhost/index/test2/1
http://localhost/index/test2/1/2
在Phalcon的路由匹配规则中,我们可以通过 $dispatcher
来接收数据:
public function test3Action(){
$a = $this->dispatcher->getParam('a');
$b = $this->dispatcher->getParam('b');
var_dump($a);
var_dump($b);
}
路由规则如下( app/config/routes.php
):
'/index/test3/(\d+)/(\d+)' => array(
'module' => 'frontend',
'controller'=>'index',
'action'=>'test3',
'a' => 1,
'b' => 2,
),
在浏览器中访问 http://localhost/index/test3/111/222
即可看到打印的结果。
返回响应数据
public function test6Action(){
return $this->response->setJsonContent(array(
'code' => 1,
'message' => 'success',
));
}
在浏览器中访问 http://localhost/index/test6
即可看到ajax返回的JSON数据。
页面跳转
Phalcon中提供了两种页面跳转方式。
redirect()
public function test4Action(){
return $this->response->redirect('https://www.marser.cn');
}
仔细观察会发现浏览器中的URL地址已经发生了变化。
forward()
public function test5Action(){
return $this->dispatcher->forward(array(
'controller' => 'test',
'action' => 'index',
));
}
此种方式的页面跳转不会改变URL地址,只是将请求转发到另一个控制器的action。
调用DI中注册的服务
DI中注册的所有服务,在控制器中都可以直接调用:
public function test7Action(){
var_dump($this->session);
var_dump($this->cookies);
var_dump($this->request);
var_dump($this->response);
var_dump($this->db);
var_dump($this->logger);
//...
}
我们可以在这里发散一下,在DI中注册我们的全局配置对象:
$di -> setShared('config', function() use($config){
return $config;
});
在控制器中直接调用( $this->config
)即可。
以上代码已托管在github:https://github.com/KevinJay/marser-phalcon-demo
最后,欢迎大家加入QQ群交流讨论:
- 广州PHP高端交流群:158587573
- Phalcon玩家群:150237524