本文主要介紹了Symfony2控制器用法,詳細分析了Symfony控制器的功能,實現技巧與相關技術細節。需要的朋友可以參考下,希望對大家有幫助。
一個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>'); } }
注意在這個例子中controller是indexAction方法,它存在於controller類別(HelloController)中。不要混淆,之所以定義一個controller類別(HelloController)只是為了方便組織多個controllers/actions在一起。一般情況下,一個controller類別會有多個controllers/actions。
上面範例中的controller相當簡單:
Namespace行是symfony2使用了PHP5.3的命名空間功能來為整個controller類別指定命名空間。
use關鍵字導入了Response類,這是我們的controller必須回傳的內容。
Controller類別名字都是由其名字後面加上Controller來定義,但是只有前面的部分才是其真正名字,為了統一起見,在後面統一添加Controller。 路由配置時只會取前面部分。
Controller類別中每個被用於真正controller的方法都會被加入一個統一的後綴Action,同樣我們在配置其路由時也只會取前面部分而忽略掉Action。把它映射到某個URL。
每個controller方法的最後必然會建立一個Response物件並回傳它。
映射一個URL到一個Controller方法:
上面範例中的controller方法傳回一個簡單的HTML頁面。如果要在瀏覽器中造訪到該頁面,那麼你需要為它建立一個route,把它對應到一個特定模式的URL上。
# app/config/routing.yml hello: pattern: /hello/{name} defaults: { _controller: AcmeHelloBundle:Hello:index }
XML格式:
<!-- app/config/routing.xml --> <route id="hello" pattern="/hello/{name}"> <default key="_controller">AcmeHelloBundle:Hello:index</default> </route>
PHP程式碼格式:
// app/config/routing.php $collection->add('hello', new Route('/hello/{name}', array( '_controller' => 'AcmeHelloBundle:Hello:index', )));
現在想URL /hello/ryan 將被對應到HelloController::indexAction() controller並將ryan傳遞給$name變數。
創造一個所謂的頁面,其實就是要建立一個controller方法和一個相關的route。
注意我們使用的指向controller方法的表示語法:AcmeHelloBundle:Hello:index
#Symfony2使用了一个非常灵活的字符串声明来指向不同的controller。它告诉Symfony2在一个名叫AcmeHelloBundle的bundle中去查找一个叫HelloController的类,并执行它的indexAction()方法。在这个例子中,我们的路由配置直接写在了app/config/ 目录下,一个更好的组织方式是把你的路由放到各自的bundle中。
路由参数作为Controller方法参变量
你已经了_controller参数 AcmeHelloBundle:Hello:index指向一个位于AcmeHelloBundle中名叫HelloController::indexAction()的方法。有趣的是路由中参数都会被传递给该方法。
<?php // src/Acme/HelloBundle/Controller/HelloController.php namespace Acme\HelloBundle\Controller; use Symfony\Bundle\FrameworkBundle\Controller\Controller; class HelloController extends Controller { public function indexAction($name) { // ... } }
上例中controller方法有一个唯一参数,$name, 它对应着route中定义的{name}占位符名称。事实上,等你执行你的controller时,Symfony2会匹配controller和route中每一个参数。
如果我修改一下Hello的路由定义:
YAML格式:
# app/config/routing.yml hello: pattern: /hello/{first_name}/{last_name} defaults: { _controller: AcmeHelloBundle:Hello:index, color: green }
XML格式:
<!-- app/config/routing.xml --> <route id="hello" pattern="/hello/{first_name}/{last_name}"> <default key="_controller">AcmeHelloBundle:Hello:index</default> <default key="color">green</default> </route>
PHP代码格式:
// app/config/routing.php $collection->add('hello', new Route('/hello/{first_name}/{last_name}', array( '_controller' => 'AcmeHelloBundle:Hello:index', 'color' => 'green', )));
这时候controller中可以获取这些参变量了:
public function indexAction($first_name, $last_name, $color) { // ... }
注意route定义中无论是占位符变量还是默认值变量都会被转化为controller方法的输入变量。当一个route匹配成功时,它会合并占位符和defaults到一个数组传递给controller。映射route参数到controller参数非常简单和灵活。它们从route到controller不匹配顺序。Symfony能够把route中参变量的名字映射到controller方法签名中的变量名字。比如{last_name} => $last_name,跟排列顺序无关。
Controller方法中的参数必须匹配route中定义的参数下面为hello route定义的controller方法将会抛出异常:
public function indexAction($last_name, $color, $first_name) { // .. }
如果我们把$foo变量变为可选变量,那么就不会抛异常了。
public function indexAction($first_name, $last_name, $color, $foo) { // .. }
并不是每一个在route中定义的参数都需要在controller中有与之对应的签名参变量的,比如hello route中定义的{$last_name} 如果对你没什么意义的话可以在controller中省略掉它。
public function indexAction($first_name, $color) { // .. }
反之,如果你在Controller签名中定义了变量,并且不是可选变量,那么必须在route中有与之对应的参数被定义。
在route定义中有一个特殊参数 _route, 它匹配route的名称(如上例中的hello)。虽然不常用,但是它也可以作为controller方法的一个参变量使用。
Request作为一个Controller方法签名变量
为了方便,你可能会让symfony传递你的Request对象作为参数到你的controller方法。这在你处理表单时尤为方便。
use Symfony\Component\HttpFoundation\Request; public function updateAction(Request $request) { $form = $this->createForm(...); $form->bindRequest($request); // ... }
Controller基类
为了方便,Symfony2定义了一个Controller基类,包含了一些常用的controller任务并给了你的controller类访问任何你需要的资源的途径。通过继承该类,你可以获得许多帮助方法。
// src/Acme/HelloBundle/Controller/HelloController.php namespace Acme\HelloBundle\Controller; use Symfony\Bundle\FrameworkBundle\Controller\Controller; use Symfony\Component\HttpFoundation\Response; class HelloController extends Controller { public function indexAction($name) { return new Response('<html><body>Hello '.$name.'!</body></html>'); } }
在Symfony中controller并不一定非得继承Controller基类,因为它内部的帮助方法等都不是必须的。你也可以继承 Symfony\Component\DependencyInjection\ContainerAware 服务容器对象可以通过container属性来访问。同时你也可以把controller定义成service。
通用的Controller任务:
尽管Controller可以干任何事情,但是大部分的controller还是要重复的干一些基础的任务。比如 重定向,跳转,渲染模板和访问核心服务等。
重定向(redirecting)
如果你想重定向你的用户到另一个页面,可以使用redirect()方法。
public function indexAction() { return $this->redirect($this->generateUrl('homepage')); }
这里generateUrl()方法是一个帮助函数,用于根据给定的route生成相应的URL。默认情况下,redirect()方法执行一个302重定向。如果要执行301重定向,那么需要修改第二个参数如下:
public function indexAction() { return $this->redirect($this->generateUrl('homepage'), 301); }
redirect()方法其实是一个简化写法,真正的代码如下:
use Symfony\Component\HttpFoundation\RedirectResponse; return new RedirectResponse($this->generateUrl('homepage'));
跳转(Forwarding)
你可以使用forward()方法很容易从一个controller到另一个controller内部。它执行的是一个内部子请求,来调用指定的controller,所以不会产生用户客户端浏览器的重定向。forward()方法返回的Response对象还将从原controller返回。
public function indexAction($name) { $response = $this->forward('AcmeHelloBundle:Hello:fancy', array( 'name' => $name, 'color' => 'green' )); // further modify the response or return it directly return $response; }
这里forward()方法使用了跟route配置中相同的字符串参数。这里传入数组参数会作为目标调用controller的参数。当将controller嵌入到模板时,也会使用同样的接口。目标调用的controller方法应该是如下定义:
public function fancyAction($name, $color) { // ... create and return a Response object }
就像为一个route创建一个controller一样,跟参数的顺序没关系。symfony2 会匹配索引键名称name到方法参数名称$name,即使顺序打乱也没关系。跟其它Controller基类方法一样,forward方法也仅仅是一个symfony2核心函数的快捷写法。一个跳转可以直接通过http_kernel服务来完成,返回一个Response对象。
$httpKernel = $this->container->get('http_kernel'); $response = $httpKernel->forward('AcmeHelloBundle:Hello:fancy', array( 'name' => $name, 'color' => 'green', ));
渲染模板:
虽然不是必须的,但是大部分controller将最终渲染一个负责生成为controller负责生成HTML的模板。renderView()方法会渲染一个模板并返回它的内容。这个返回内容可以用作创建Response对象,以供controller返回使用。
$content = $this->renderView('AcmeHelloBundle:Hello:index.html.twig', array('name' => $name)); return new Response($content);
上面的代码完全可以更进一步的使用下面的代码形式来写:
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') %} <p class="flash-notice"> {{ app.session.flash('notice') }} </p> {% endif %}
PHP代码:
<?php if ($view['session']->hasFlash('notice')): ?> <p class="flash-notice"> <?php echo $view['session']->getFlash('notice') ?> </p> <?php endif; ?>
这样设计,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在模板和行为中取得request参数的方法
以上是詳解Symfony2控制器的用法的詳細內容。更多資訊請關注PHP中文網其他相關文章!

由于Windows已成为首选的游戏平台,因此确定其面向游戏的功能就显得尤为重要。其中之一是能够在Windows11上校准XboxOne控制器。借助内置的手动校准,您可以摆脱漂移、随机移动或性能问题,并有效地对齐X、Y和Z轴。如果可用选项不起作用,您可以随时使用第三方XboxOne控制器校准工具。让我们来了解一下!如何在Windows11上校准我的Xbox控制器?在继续操作之前,请确保将控制器连接到电脑并更新XboxOne控制器的驱动程序。当您使用它时,还要安装任何可用的固件更新。1.使用Wind

从零开始学习Laravel:控制器方法调用详解在Laravel的开发中,控制器是一个非常重要的概念。控制器起到了连接模型和视图的桥梁作用,负责处理来自路由的请求,并返回相应的数据给视图展示。控制器中的方法可以被路由调用,这篇文章将详细介绍如何编写并调用控制器中的方法,同时会提供具体的代码示例。首先,我们需要创建一个控制器。可以使用Artisan命令行工具来生

PHP是一种非常流行的编程语言,而CodeIgniter4是一种常用的PHP框架。在开发Web应用程序时,使用框架是非常有帮助的,它可以加速开发过程、提高代码质量、降低维护成本。本文将介绍如何使用CodeIgniter4框架。安装CodeIgniter4框架CodeIgniter4框架可以从官方网站(https://codeigniter.com/)下载。下

Python函数介绍:abs函数的用法和示例一、abs函数的用法介绍在Python中,abs函数是一个内置函数,用于计算给定数值的绝对值。它可以接受一个数字参数,并返回该数字的绝对值。abs函数的基本语法如下:abs(x)其中,x是要计算绝对值的数值参数,可以是整数或浮点数。二、abs函数的示例下面我们将通过一些具体的示例来展示abs函数的用法:示例1:计算

在laravel中,控制器(Controller)是一个类,用于实现一定的功能;控制器能将相关的请求处理逻辑组成一个单独的类。控制器中存放中一些方法,实现一定的功能,通过路由调用控制器,不再使用回调函数;控制器被存放在“app/Http/Controllers”目录中。

Python函数介绍:isinstance函数的用法和示例Python是一门功能强大的编程语言,提供了许多内置函数,使得编程变得更加方便和高效。其中一个非常有用的内置函数是isinstance()函数。本文将介绍isinstance函数的用法和示例,并提供具体的代码示例。isinstance()函数用于判断一个对象是否是指定的类或类型的实例。该函数的语法如下

在Laravel学习指南中,控制器方法的调用是一个非常重要的主题。控制器扮演着连接路由和模型的桥梁的角色,在应用程序中起着至关重要的作用。本文将介绍控制器方法调用的最佳实践,并提供具体的代码示例帮助读者更好地理解。首先,让我们来了解控制器方法的基本结构。在Laravel中,控制器类通常存放在app/Http/Controllers目录下,每个控制器类包含多个

Python函数介绍:getattr函数的用法和示例在Python中,getattr()是一个内置函数,用于获取对象的属性值。在不知道对象的属性名称的情况下,可以使用getattr()函数来动态地访问属性。本文将介绍getattr()函数的语法、用法和示例。getattr()函数的语法如下:getattr(object,name[,default])参数


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

mPDF
mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

SublimeText3漢化版
中文版,非常好用

Dreamweaver Mac版
視覺化網頁開發工具

EditPlus 中文破解版
體積小,語法高亮,不支援程式碼提示功能

Safe Exam Browser
Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。