Home Backend Development PHP Tutorial Detailed explanation of the usage of Symfony2 controller

Detailed explanation of the usage of Symfony2 controller

Jan 05, 2018 pm 05:43 PM
controller usage

This article mainly introduces the usage of Symfony2 controller, and analyzes the functions, implementation techniques and related technical details of Symfony controller in detail. Friends in need can refer to it. I hope it will be helpful to everyone.

A controller is a PHP function you create that receives an HTTP request (request) and creates and returns an HTTP reply (Response). The response object (Response) can be an HTML page, an XML document, a serialized JSON array, an image, a redirect, a 404 error or anything you want. The controller can contain any logic needed to render the content of your page.

The following is the simplest example of a controller, which just prints a Hello world!

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

The ultimate goal of the Controller is the same, which is to create and return a Response object. Following this idea, you can read information from the request object, load database resources, send emails, or write information in the user's Session. But in all cases, the Controller will eventually return a Response object and be distributed to the client.

For example, the following situation:

Controller A prepares a Response object to represent the website homepage content.
Controller B reads the slug parameter from the Request, loads a blog content from the database and creates a Response object to display the blog. If the slug does not exist in the database, it will create and return a Response object with a 404 status code.

Controller C processes a slave contact form, which reads the form information from the Request object and saves the contact information. Go to the database and send an email to the administrator. Finally, it creates a Response object that redirects the client browser to the contact form thank you page.

Life cycle of Requests, Controller, Response

Every Request processed in the Symfony2 project goes through the same simple life cycle. The framework is responsible for repetitive tasks and ultimately executes a controller, which will contain your application code:

1. Each Request will be handled by a unified front-end controller file (for example, app.php, or app_dev .php) and it will launch the application.
2.Router reads the URI information from the Request, finds the Route that matches it, and reads the _controller parameter from the Route.
3. The controller of the successfully matched route is executed, and the code in the controller creates and returns a Response object.
4. The HTTP header and the generated Response object content will be sent back to the client.

Creating a page is as easy as creating a controller and creating a route to map a URL to the controller.

Note: Although the front-end controller and controller are similar in name, they are actually different.
A front-end controller is a PHP file stored in the web directory, through which all requests will be redirected. Every application will have a production front-end controller app.php and a development front-end controller app_dev.php. You don't need to edit, view or worry about them.

Look at a simple Controller: Any PHP callable content (such as a function, object method or a Closure) can become a controller. In Symfongy2, a controller is usually a single method in the controller object. Controllers are also often called 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(&#39;<html><body>Hello &#39;.$name.&#39;!</body></html>&#39;);
 }
}
Copy after login

Note that in this example the controller is the indexAction method, which exists in the controller class (HelloController). Don't be confused, the reason why a controller class (HelloController) is defined is just to facilitate organizing multiple controllers/actions together. Generally, a controller class will have multiple controllers/actions.

The controller in the above example is quite simple:

The Namespace line is where symfony2 uses the namespace feature of PHP5.3 to specify a namespace for the entire controller class. The
use keyword imports the Response class, which is what our controller must return.

Controller class names are defined by adding Controller to the end of its name, but only the front part is its real name. For the sake of unification, Controller is added at the end. Only the first part will be taken during routing configuration.

Every method in the Controller class that is used for the real controller will be added with a unified suffix Action. Similarly, when configuring its routing, we will only take the first part and ignore the Action. Map it to a URL.

At the end of each controller method, a Response object must be created and returned.

Mapping a URL to a Controller method:

The controller method in the above example returns a simple HTML page. If you want to access this page in a browser, you need to create a route for it and map it to a URL with a specific pattern.

# app/config/routing.yml
hello:
 pattern:  /hello/{name}
 defaults:  { _controller: AcmeHelloBundle:Hello:index }
Copy after login

XML format:

<!-- app/config/routing.xml -->
<route id="hello" pattern="/hello/{name}">
 <default key="_controller">AcmeHelloBundle:Hello:index</default>
</route>
Copy after login

PHP code format:

// app/config/routing.php
$collection->add(&#39;hello&#39;, new Route(&#39;/hello/{name}&#39;, array(
 &#39;_controller&#39; => &#39;AcmeHelloBundle:Hello:index&#39;,
)));
Copy after login

Now want the URL /hello/ryan to be mapped to the HelloController::indexAction() controller and pass ryan Give the $name variable.

Creating a so-called page is actually creating a controller method and a related route.

Note the syntax we use to point to the controller method: 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)
 {
  // ...
 }
}
Copy after login

上例中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 }
Copy after login

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>
Copy after login

PHP代码格式:

// app/config/routing.php
$collection->add(&#39;hello&#39;, new Route(&#39;/hello/{first_name}/{last_name}&#39;, array(
 &#39;_controller&#39; => &#39;AcmeHelloBundle:Hello:index&#39;,
 &#39;color&#39;  => &#39;green&#39;,
)));
Copy after login

这时候controller中可以获取这些参变量了:

public function indexAction($first_name, $last_name, $color)
{
 // ...
}
Copy after login

注意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)
{
 // ..
}
Copy after login

如果我们把$foo变量变为可选变量,那么就不会抛异常了。

public function indexAction($first_name, $last_name, $color, $foo)
{
 // ..
}
Copy after login

并不是每一个在route中定义的参数都需要在controller中有与之对应的签名参变量的,比如hello route中定义的{$last_name} 如果对你没什么意义的话可以在controller中省略掉它。

public function indexAction($first_name, $color)
{
 // ..
}
Copy after login

反之,如果你在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);
 // ...
}
Copy after login

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(&#39;<html><body>Hello &#39;.$name.&#39;!</body></html>&#39;);
 }
}
Copy after login

在Symfony中controller并不一定非得继承Controller基类,因为它内部的帮助方法等都不是必须的。你也可以继承 Symfony\Component\DependencyInjection\ContainerAware 服务容器对象可以通过container属性来访问。同时你也可以把controller定义成service。

通用的Controller任务:

尽管Controller可以干任何事情,但是大部分的controller还是要重复的干一些基础的任务。比如 重定向,跳转,渲染模板和访问核心服务等。

重定向(redirecting)

如果你想重定向你的用户到另一个页面,可以使用redirect()方法。

public function indexAction()
{
 return $this->redirect($this->generateUrl(&#39;homepage&#39;));
}
Copy after login

这里generateUrl()方法是一个帮助函数,用于根据给定的route生成相应的URL。默认情况下,redirect()方法执行一个302重定向。如果要执行301重定向,那么需要修改第二个参数如下:

public function indexAction()
{
 return $this->redirect($this->generateUrl(&#39;homepage&#39;), 301);
}
Copy after login

redirect()方法其实是一个简化写法,真正的代码如下:

use Symfony\Component\HttpFoundation\RedirectResponse;
return new RedirectResponse($this->generateUrl(&#39;homepage&#39;));
Copy after login

跳转(Forwarding)

你可以使用forward()方法很容易从一个controller到另一个controller内部。它执行的是一个内部子请求,来调用指定的controller,所以不会产生用户客户端浏览器的重定向。forward()方法返回的Response对象还将从原controller返回。

public function indexAction($name)
{
 $response = $this->forward(&#39;AcmeHelloBundle:Hello:fancy&#39;, array(
  &#39;name&#39; => $name,
  &#39;color&#39; => &#39;green&#39;
 ));
 // further modify the response or return it directly
 return $response;
}
Copy after login

这里forward()方法使用了跟route配置中相同的字符串参数。这里传入数组参数会作为目标调用controller的参数。当将controller嵌入到模板时,也会使用同样的接口。目标调用的controller方法应该是如下定义:

public function fancyAction($name, $color)
{
 // ... create and return a Response object
}
Copy after login

就像为一个route创建一个controller一样,跟参数的顺序没关系。symfony2 会匹配索引键名称name到方法参数名称$name,即使顺序打乱也没关系。跟其它Controller基类方法一样,forward方法也仅仅是一个symfony2核心函数的快捷写法。一个跳转可以直接通过http_kernel服务来完成,返回一个Response对象。

$httpKernel = $this->container->get(&#39;http_kernel&#39;);
$response = $httpKernel->forward(&#39;AcmeHelloBundle:Hello:fancy&#39;, array(
 &#39;name&#39; => $name,
 &#39;color&#39; => &#39;green&#39;,
));
Copy after login

渲染模板:

虽然不是必须的,但是大部分controller将最终渲染一个负责生成为controller负责生成HTML的模板。renderView()方法会渲染一个模板并返回它的内容。这个返回内容可以用作创建Response对象,以供controller返回使用。

$content = $this->renderView(&#39;AcmeHelloBundle:Hello:index.html.twig&#39;, array(&#39;name&#39; => $name));
return new Response($content);
Copy after login

上面的代码完全可以更进一步的使用下面的代码形式来写:

return $this->render(&#39;AcmeHelloBundle:Hello:index.html.twig&#39;, array(&#39;name&#39; => $name));
Copy after login

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

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

$templating = $this->get(&#39;templating&#39;);
$content = $templating->render(&#39;AcmeHelloBundle:Hello:index.html.twig&#39;, array(&#39;name&#39; => $name));
Copy after login

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

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

访问其它服务

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

$request = $this->getRequest();
$templating = $this->get(&#39;templating&#39;);
$router = $this->get(&#39;router&#39;);
$mailer = $this->get(&#39;mailer&#39;);
Copy after login

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

$ php app/console container:debug
Copy after login

管理错误和404页面

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

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

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

throw new \Exception(&#39;Something went wrong!&#39;);
Copy after login

管理Session

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

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

Flash 消息

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

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

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

Twig

{% if app.session.hasFlash(&#39;notice&#39;) %}
 <p class="flash-notice">
  {{ app.session.flash(&#39;notice&#39;) }}
 </p>
{% endif %}
Copy after login

PHP代码:

<?php if ($view[&#39;session&#39;]->hasFlash(&#39;notice&#39;)): ?>
 <p class="flash-notice">
  <?php echo $view[&#39;session&#39;]->getFlash(&#39;notice&#39;) ?>
 </p>
<?php endif; ?>
Copy after login

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

Response对象

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

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

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

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

请求对象Request

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

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

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

总结思考:

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

相关推荐:

详解Symfony模板快捷变量的用法

详解Symfony在模板和行为中取得request参数的方法

详解symfony如何使用命令创建项目

The above is the detailed content of Detailed explanation of the usage of Symfony2 controller. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
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

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

How to properly calibrate your Xbox One controller on Windows 11 How to properly calibrate your Xbox One controller on Windows 11 Sep 21, 2023 pm 09:09 PM

Since Windows has become the gaming platform of choice, it's even more important to identify its gaming-oriented features. One of them is the ability to calibrate an Xbox One controller on Windows 11. With built-in manual calibration, you can get rid of drift, random movement, or performance issues and effectively align the X, Y, and Z axes. If the available options don't work, you can always use a third-party Xbox One controller calibration tool. Let’s find out! How do I calibrate my Xbox controller on Windows 11? Before proceeding, make sure you connect your controller to your computer and update your Xbox One controller's drivers. While you're at it, also install any available firmware updates. 1. Use Wind

Analyze the usage and classification of JSP comments Analyze the usage and classification of JSP comments Feb 01, 2024 am 08:01 AM

Classification and Usage Analysis of JSP Comments JSP comments are divided into two types: single-line comments: ending with, only a single line of code can be commented. Multi-line comments: starting with /* and ending with */, you can comment multiple lines of code. Single-line comment example Multi-line comment example/**This is a multi-line comment*Can comment on multiple lines of code*/Usage of JSP comments JSP comments can be used to comment JSP code to make it easier to read

Usage of WPSdatedif function Usage of WPSdatedif function Feb 20, 2024 pm 10:27 PM

WPS is a commonly used office software suite, and the WPS table function is widely used for data processing and calculations. In the WPS table, there is a very useful function, the DATEDIF function, which is used to calculate the time difference between two dates. The DATEDIF function is the abbreviation of the English word DateDifference. Its syntax is as follows: DATEDIF(start_date,end_date,unit) where start_date represents the starting date.

Learning Laravel from scratch: Detailed explanation of controller method invocation Learning Laravel from scratch: Detailed explanation of controller method invocation Mar 10, 2024 pm 05:03 PM

Learning Laravel from scratch: Detailed explanation of controller method invocation In the development of Laravel, controller is a very important concept. The controller serves as a bridge between the model and the view, responsible for processing requests from routes and returning corresponding data to the view for display. Methods in controllers can be called by routes. This article will introduce in detail how to write and call methods in controllers, and will provide specific code examples. First, we need to create a controller. You can use the Artisan command line tool to create

How to use CodeIgniter4 framework in php? How to use CodeIgniter4 framework in php? May 31, 2023 pm 02:51 PM

PHP is a very popular programming language, and CodeIgniter4 is a commonly used PHP framework. When developing web applications, using frameworks is very helpful. It can speed up the development process, improve code quality, and reduce maintenance costs. This article will introduce how to use the CodeIgniter4 framework. Installing the CodeIgniter4 framework The CodeIgniter4 framework can be downloaded from the official website (https://codeigniter.com/). Down

Introduction to Python functions: Usage and examples of abs function Introduction to Python functions: Usage and examples of abs function Nov 03, 2023 pm 12:05 PM

Introduction to Python functions: usage and examples of the abs function 1. Introduction to the usage of the abs function In Python, the abs function is a built-in function used to calculate the absolute value of a given value. It can accept a numeric argument and return the absolute value of that number. The basic syntax of the abs function is as follows: abs(x) where x is the numerical parameter to calculate the absolute value, which can be an integer or a floating point number. 2. Examples of abs function Below we will show the usage of abs function through some specific examples: Example 1: Calculation

Introduction to Python functions: Usage and examples of isinstance function Introduction to Python functions: Usage and examples of isinstance function Nov 04, 2023 pm 03:15 PM

Introduction to Python functions: Usage and examples of the isinstance function Python is a powerful programming language that provides many built-in functions to make programming more convenient and efficient. One of the very useful built-in functions is the isinstance() function. This article will introduce the usage and examples of the isinstance function and provide specific code examples. The isinstance() function is used to determine whether an object is an instance of a specified class or type. The syntax of this function is as follows

How to correctly use the exit function in C language How to correctly use the exit function in C language Feb 18, 2024 pm 03:40 PM

How to use the exit function in C language requires specific code examples. In C language, we often need to terminate the execution of the program early in the program, or exit the program under certain conditions. C language provides the exit() function to implement this function. This article will introduce the usage of exit() function and provide corresponding code examples. The exit() function is a standard library function in C language and is included in the header file. Its function is to terminate the execution of the program, and can take an integer

See all articles