Home >Backend Development >PHP Tutorial >Symfony2学习笔记之控制器用法详解_PHP

Symfony2学习笔记之控制器用法详解_PHP

WBOY
WBOYOriginal
2016-05-28 11:48:11719browse

本文实例讲述了Symfony2控制器用法。分享给大家供大家参考,具体如下:

一个controller是你创建的一个PHP函数,它接收HTTP请求(request)并创建和返回一个HTTP回复(Response)。回复对象(Response)可以是一个HTML页面,一个XML文档,一个序列化的JSON数组,一个图片,一个重定向,一个404错误或者任何你想要的内容。controller中可以包含任何渲染你页面内容的所需要的逻辑。

下面是一个controller最简单的例子,仅仅打印一个Hello world!

use Symfony\Component\HttpFoundation\Response;
public function helloAction()
{
 return new Response('Hello world!');
}

Controller的终极目标都是相同的那就是创建并返回一个Response对象。按照这个思路,你可以从request对象读取信息,加载数据库资源,发送email,或者在用户的Session中写入信息。但是所有情况下,Controller将最终都会返回一个Response对象并被分发会客户端。

比如如下情况:

Controller A 准备一个Response对象来表现网站homepage内容。
Controller B 从Request中读取slug参数从数据库中加载一个blog内容并创建一个Response对象来显示这个blog。如果slug在数据库中不存在,它将创建并返回一个带有404状态码的Response对象.

Controller C 处理一个从联系表单,它从Request对象中读取表单信息,保存联系信息到数据库并发邮件给管理员。最后,它创建一个Response对象重定向客户端浏览器到联系表单感谢页面。

Requests,Controller, Response的生命周期

Symfony2项目中处理的每一个Request都是经过了相同的简单生命周期。框架负责重复的任务,最终执行一个controller,该controller会包含你的应用程序代码:

1.每个Request都会被一个统一的前端控制器文件(比如,app.php,或者app_dev.php)处理,它会启动应用程序。
2.Router从Request中读取URI信息,并找到匹配它的Route,从该Route中读取_controller参数。
3.匹配成功的route的controller被执行,controller中的代码创建并返回一个Response对象。
4.HTTP头和生成的Response对象内容将会被发回客户端。

创建一个页面跟创建一个controller一样容易,创建一个路由来映射一个URL到该controller。

注意:尽管从名字上来看,前端控制器和controller差不多,其实它们是不同的。
一个前端控制器是一个存放于web目录下的PHP文件,多有的Request都会通过它被重定向。每一个应用程序都会有一个产品前端控制器app.php和一个开发用的前端控制器app_dev.php。你不需要编辑,查看或者担心它们。

看一个简单的Controller: 任何的PHP可调用内容(比如函数,对象方法或者一个Closure)都可以成为一个controller。Symfongy2中,一个controller通常为controller对象中一个单一的方法。Controllers通常也被称为actions。

// src/Acme/HelloBundle/Controller/HelloController.php
namespace Acme\HelloBundle\Controller;
use Symfony\Component\HttpFoundation\Response;
class HelloController
{
 public function indexAction($name)
 {
  return new Response('<html><body>Hello '.$name.'!</body></html>');
 }
}

代码如下:

return $this->render('AcmeHelloBundle:Hello:index.html.twig', array('name' => $name));

这两种情况下,AcmeHelloBundle中的模板Resources/views/Hello/index.html.twig都会被渲染。

renderview()方法是如下代码的快捷写法:

$templating = $this->get('templating');
$content = $templating->render('AcmeHelloBundle:Hello:index.html.twig', array('name' => $name));

当然也可以在子目录中渲染模板

$templating->render('AcmeHelloBundle:Hello/Greetings:index.html.twig', array('name' => $name));
// index.html.twig 存放于 Resources/views/Hello/Greetings 目录.

访问其它服务

只要是继承了Controller基类,你就可以通过get()方法访问symfony2的服务了。比如:

$request = $this->getRequest();
$templating = $this->get('templating');
$router = $this->get('router');
$mailer = $this->get('mailer');

Symfony2中还有无数的可用服务,同时也鼓励你定义自己的服务。要查看所有的服务,可以使用container:debug 命令行工具

$ php app/console container:debug

管理错误和404页面

当一些东西没有找到,你应该重置HTTP协议返回一个404 回复。要做到这个,你将抛出一个特殊类型的异常。如果你是继承了Controller基类,则:

public function indexAction()
{
 $product = // retrieve the object from database
 if (!$product) {
  throw $this->createNotFoundException('The product does not exist');
 }
 return $this->render(...);
}

createNotFoundException()方法创建一个特定的NotFoundHttpException对象,它最终触发404 HTTP回复。当然你从你的controller方法中可以抛出任何类型的Exception 类,Symfony2会自动返回一个500 HTTP回复代码。

throw new \Exception('Something went wrong!');

管理Session

Symfony2 提供了一个非常好的Session对象,你可以用它来在请求之间存贮有关用户的信息。默认情况下,Symfony2 通过PHP本身的Session保存属性到cookie。在任何controller中存储和获取Session信息将非常容易:

$session = $this->getRequest()->getSession();
// 为用户的后一个请求使用存储一个属性
$session->set('foo', 'bar');
// 在另一个controller中为另一个请求获取该属性
$foo = $session->get('foo');
// 设置用户的本地化语言
$session->setLocale('fr');

Flash 消息

你可以为特定的请求存储少量的消息到用户的Session。这在处理一个表单时非常有用,你想重定向和一个特定的信息显示在下一个请求中。这种类型的消息被称为Flash消息。比如,假设你处理一个表单提交:

public function updateAction()
{
 $form = $this->createForm(...);
 $form->bindRequest($this->getRequest());
 if ($form->isValid()) {
  // 做些排序处理
  $this->get('session')->setFlash('notice', 'Your changes were saved!');
  return $this->redirect($this->generateUrl(...));
 }
 return $this->render(...);
}

此例中,在处理完请求后,controller设置了一个notice flash消息并作了重定向。名字notice没什么意义,只是用于标识该消息。在下一个活动的模板中,下面的代码能够渲染这个notic消息:

Twig

{% if app.session.hasFlash('notice') %}
 <div class="flash-notice">
  {{ app.session.flash('notice') }}
 </div>
{% endif %}

PHP代码:

<&#63;php if ($view['session']->hasFlash('notice')): &#63;>
 <div class="flash-notice">
  <&#63;php echo $view['session']->getFlash('notice') &#63;>
 </div>
<&#63;php endif; &#63;>

这样设计,flash消息就能够为准确的某个请求存在了。他们一般被设计出来就是用于重定向的。

Response对象

作为一个Controller来说,唯一必须做到的是返回一个Response对象。

Response对象是一个PHP代码对HTTP Response的抽象。
HTTP Response是一个基于文本的消息有HTTP headers和 返回给客户端的内容组成。

//创建一个简单的Response对象,默认状态码为200
$response = new Response('Hello ' .$name, 200);
//创建一个基于JSON的Response对象,状态码也为200
$response = new Response(json_encode(array('name'=>$name)));
$response->headers->set('content-type','application/json');

其中headers属性是一个HeaderBag对象,内部包含许多有用的方法来读取和改变Response的头信息。头名字被标准化使用Content-Type 与content-type或者content_type效果等同。

请求对象Request

除了路由占位符的值以外,如果继承了Controller基类那么该controller还可以访问Request对象。

$request = $this->getRequest();
$request->isXmlHttpRequest(); // 判断是不是Ajax请求
$request->getPreferredLanguage(array('en','fr'));
$request->query->get('page'); // 获取$_GET 参数
$request->request->get('page'); //获取$_POST参数

跟Response对象一样,Request对象的头也保存在HeaderBag对象中,可以很方便的被访问。

总结思考:

无论何时,你创建一个页面,你最终需要为它写一些包含逻辑的代码。在Symfony中,这叫一个controller, 它是一个PHP的函数,它可以为了最后返回一个Response对象给用户可以做需要的任何事情。简单的说,你可以选择继承一个Controller基类,它包含了许多执行controller通用任务的快捷方法。比如,你不想把HTML代码写入你的controller, 你可以使用render()方法来渲染并返回一个模板内容。

希望本文所述对大家基于Symfony框架的PHP程序设计有所帮助。

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn