Create your first Symfony page


Creating a new page - whether HTML or JSON output - is a simple "two-step" operation:

  1. ##Create a route: The route is a URL pointing to your page (such as /about), and mapped to a controller at the same time.

  2. Create a Controller:Controller( controller) is the function you write to construct the page. You need to get the request request information sent and use it to create a Symfony Response object to contain HTML content, JSON string or other

Just like every interaction on the Internet starts with an HTTP request, your task is pure and simple: understand the request and return a reply.

Create a page: routes and controllers

Before you begin, make sure you have read Installing and Configuring Symfony chapter, and you can already access the Symfony program in the browser.

Suppose you want to create a new one/lucky/numberPage, used to generate a random lucky number and output it. Then, first create a class and add a method to be executed when someone visits /lucky/number:

// src/AppBundle/Controller/LuckyController.phpnamespace AppBundle\Controller; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;use Symfony\Component\HttpFoundation\Response; class LuckyController{
    /**
     * @Route("/lucky/number")
     */
    public function numberAction()
    {
        $number = rand(0, 100);         return new Response(
            '<html><body>Lucky number: '.$number.'</body></html>'
        );
    }}


Test before you start

http://localhost:8000/lucky/number

If you are at If the virtual host is correctly set up on Apache or Nginx, you can put http:// Replace the localhost:8000 part with your own hostname, such as http://symfony.dev/app_dev.php/lucky/number.

If you see a lucky number being output, congratulations! But before you play lotto, you first need to understand how it works.

numberAction#@Route of above is called annotation , which defines URL matching. You can also write routes in YAML (or other formats): please refer to the Routes chapter. In fact, most routing routines in the documentation have "labels" to show the configuration for each format

Comment out the method below - numberAction- Known as a controller, this is where you control the page. The only principle is: a controllermustreturn a Symfony Response to objects (you will eventually learn to use this principle).

Create a JSON response

##The Response object returned in the controller can contain HTML, JSON or even binary files such as images or PDFs. You can easily set HTTP header information or HTTP status code.

Assuming you want to create a JSON return value, you only need LuckyController and then Add a method:

  // src/AppBundle/Controller/LuckyController.php // ...class LuckyController{
    // ...     /**
     * @Route("/api/lucky/number")
     */
    public function apiNumberAction()
    {
        $data = array(
            'lucky_number' => rand(0, 100),
        );         return new Response(
            json_encode($data),
            200,
            array('Content-Type' => 'application/json')
        );
    }}


Test it in the browser

http://localhost:8000/api/lucky/number

You can also simplify the code to Super easy to useJsonResponse

// src/AppBundle/Controller/LuckyController.php // ...// --> don't forget this new use statement 别忘了这行新的use声明use Symfony\Component\HttpFoundation\JsonResponse; class LuckyController{
    // ...     /**
     * @Route("/api/lucky/number")
     */
    public function apiNumberAction()
    {
        $data = array(
            'lucky_number' => rand(0, 100),
        );         // calls json_encode and sets the Content-Type header
        // 自动调用json_encode并设置Content-Type头
        return new JsonResponse($data);
    }}


Dynamic URL matching: / lucky / number / {count} ##¶

nest, you did a good job but Symfony's routing can do more. Suppose you want users to be able to go to ! /lucky/number/5 to immediately generate the lucky number 5, update the route, and make it have a { at the end wildcard}Wildcard:

注释:// src/AppBundle/Controller/LuckyController.php // ...class LuckyController{
    /**
     * @Route("/lucky/number/{count}")
     */
    public function numberAction()
    {
        // ...
    }     // ...}
YAML:# app/config/routing.ymllucky_number:
    path:     /lucky/number/{count}
    defaults: { _controller: AppBundle:Lucky:number }
XML:<!-- app/config/routing.xml --><?xml version="1.0" encoding="UTF-8" ?><routes xmlns="http://symfony.com/schema/routing"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xsi:schemaLocation="http://symfony.com/schema/routing        http://symfony.com/schema/routing/routing-1.0.xsd">     <route id="lucky_number" path="/lucky/number/{count}">
        <default key="_controller">AppBundle:Lucky:number</default>
    </route></routes>
PHP:// app/config/routing.phpuse Symfony\Component\Routing\RouteCollection;use Symfony\Component\Routing\Route; $collection = new RouteCollection();$collection->add('lucky_number', new Route('/lucky/number/{count}', array(
    '_controller' => 'AppBundle:Lucky:number',))); return $collection;

Because of the {count} placeholder, the page URL becomes It’s different. Now it requires the URL to match /lucky/number/*, like /lucky/number/5. This way you can receive and use this value in your controller:

// src/AppBundle/Controller/LuckyController.php// ... class LuckyController{     /**
     * @Route("/lucky/number/{count}")
     */
    public function numberAction($count)
    {
        $numbers = array();
        for ($i = 0; $i < $count; $i++) {
            $numbers[] = rand(0, 100);
        }
        $numbersList = implode(', ', $numbers);         return new Response(
            '<html><body>Lucky numbers: '.$numbersList.'</body></html>'
        );
    }     // ...}

go to/lucky/number/ xxTest it, replace xx with any number:

##http://localhost:8000/api/lucky/number/7

You should see the lucky number 7 being output! Add a $placeholder parameter in the controller, and you can get any {placeholder}## in the route #Just make sure that the placeholder values ​​have the same name.

System-routing can also be donemore , such as supporting multiple placeholders (such as /blog/{category}/{page}), so that the placeholder The optional and mandatory placeholders match a regular expression (e.g. {count} must be is a number).

Look for more in the route chapter i.e. Can become a routing expert.

Rendering template (using container)

##If you return HTML in the controller, you may need to render the template. Fortunately, Symfony has Twig: an easy-to-learn template language that is powerful yet quite fun.

Currently,

LuckyController does not inherit any base class. The easiest way to reference Twig (or other Symfony tools) at this time is to inherit Symfony’s Controller base class:

// src/AppBundle/Controller/LuckyController.php  
// ...
// --> add this new use statement
use Symfony\Bundle\FrameworkBundle\Controller\Controller; 
class LuckyController extends Controller
{    // ...}

Use template service

These don't change anything, but bring you into Symfony's containers/containers : This is an array-like object that allows you to extract system-level every useful object. These useful objects are called Services (services), of which Symfony sends a dedicated A service object for rendering templates, one for logging, and many, many more.

Rendering the Twig template, the requested service name is templating:

// src/AppBundle/Controller/LuckyController.php // ...class LuckyController extends Controller{
    /**
     * @Route("/lucky/number/{count}")
     */
    public function numberAction($count)
    {
        // ...
        $numbersList = implode(', ', $numbers);         $html = $this->container->get('templating')->render(
            'lucky/number.html.twig',
            array('luckyNumberList' => $numbersList)
        );         return new Response($html);
    }     // ...}


# "Service container" is very important. During the learning process, you will Master a lot of relevant knowledge. For now, you just need to understand that it holds a lot of objects, and then you can pass them by "nickname" like templating or logger ) Use get() to get any of them. templating service is an instance of TwigEngine, with a in it render() method.

#But it can be simpler! By inheriting the Controller base class, you can use many shortcut methods, such as render()

// src/AppBundle/Controller/LuckyController.php // .../**
 * @Route("/lucky/number/{count}")
 */public function numberAction($count){
    // ...     /*
    $html = $this->container->get('templating')->render(
        'lucky/number.html.twig',
        array('luckyNumberList' => $numbersList)
    );
 
    return new Response($html);
    */     // render: a shortcut that does the same as above 快捷方法
    return $this->render(
        'lucky/number.html.twig',
        array('luckyNumberList' => $numbersList)
        );
  }

For information on how shortcut methods in controllers work, please refer to the controller chapter.

Advanced users please refer toHow to define a controller as a service .

Create template

If you Now refresh the page and you will get an error:

Cannot find template "lucky/number.html.twig"

Fix it by creating a new app/Resources/views/lucky directory and then number.html.twigPlace it in:

##
枝条:{# app/Resources/views/lucky/number.html.twig #}
     {% extends 'base.html.twig' %} 
     {% block body %} <h1>Lucky Numbers: {{ luckyNumberList }}</h1>
    {% endblock %}
PHP:<!-- app/Resources/views/lucky/number.html.php -->
<?php $view->extend('base.html.php') ?> 
<?php $view['slots']->start('body') ?>   
 <h1>Lucky Numbers: 
<?php echo $view->escape($luckyNumberList) ?>
<?php $view['slots']->stop() ?>

Twig welcomes you! This simple file already demonstrates basic functionality: syntax like {{ variableName }} is used to print something. And luckyNumberListThis variable is your render() Pass it in the method.

% extends 'base.html.twig' % corresponds to a layout file, they are located at app/Resources/views/base.html.twig, this file exists with the creation of the Symfony project. It's rather plain (just an unstyled HTML structure) for you to customize. {% block body %} part is the inheritance system/inheritance system using the twig template , and the future period will be placed at the corresponding position in the layout of the content parent template base.html.twig.

Refresh the page immediately

##http://localhost:8000/ lucky / number / 9

If you look at the page source, you will see the complete HTML skeleton, thanks to base.html.twig.

#This is only a very small part of the power of Twig. If you want to master Twig's syntax, array loops, output other templates and even more cool features, you should refer to Creating and using templates.

Browse the entire project

##You have created a flexible URL, rendered a template using inheritance, and output a JSON response.

#It’s time to go through the files in your project and remove their aura of mystery. Previously you have been working in two extremely important folders:

app/

Content profiles and templates. Generally speaking, as long as is not , all materials in PHP code are placed here.


src/

Where your PHP program is 99% of the time you will be working in src/ (PHP file) or app/ (other stuff) under. As your technical skills improve, you will learn what is happening under each folder. There are also other contents in the

app/ directory, like app/AppKernel.php Yes, you need to use it to open a new bundle (it is one of the few PHP files under app/).

src/ There is currently only one directory under the directory - src/AppBundle- Everything is in here. A package, like a "plugin", you can find open source bundles and install them into your project, but Even your own code is included in a bundle - typically an AppBundle (although there's nothing special about this bundle). For a deeper understanding of bundling, and why you should create multiple bundles (hint: share code between projects), see Bundle Systemchapter.

#So what about the other folders in the project?

web/

It is the document root directory of the entire project and can be made public Access files such as CSS, images and files used to execute the application (app_dev.php and app.php) Symfony front-end controller (front-end controller).


##tests/

##Automated tests for your program (such as unit tests /unittests) are stored here.


##bin/

## is used to store binary files. The most important thing is the

console file, which is used to control the execution of Symfony commands.

var/

These are the automatically generated files that are stored places, such as cache files (

var/cache/) and log files (var/logs/ ). ##vendor/


Through dependency managerComposer, third-party libraries, packages, bundles is downloaded here. You should not edit anything in this directory.

Symfony is flexible. You can override the default directory structure if necessary. Refer to How to override Symfony’s defaultdirectory structure.

Program level configuration

Symfony has several built-in native Bundle (open your app/AppKernel.php file to view), you can install more .bundles. The main configuration file is app/config/config.yml

YAML:# app/config/config.yml # ...framework:
    secret: '%secret%'
    router:
    resource: '%kernel.root_dir%/config/routing.yml'
    # ...twig:
    debug:            '%kernel.debug%'
    strict_variables: '%kernel.debug%' # ...
XML:<!-- app/config/config.xml --><?xml version="1.0" encoding="UTF-8" ?><container xmlns="http://symfony.com/schema/dic/services"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xmlns:framework="http://symfony.com/schema/dic/symfony"    xmlns:twig="http://symfony.com/schema/dic/twig"    xsi:schemaLocation="http://symfony.com/schema/dic/services        http://symfony.com/schema/dic/services/services-1.0.xsd        http://symfony.com/schema/dic/symfony        http://symfony.com/schema/dic/symfony/symfony-1.0.xsd        http://symfony.com/schema/dic/twig        http://symfony.com/schema/dic/twig/twig-1.0.xsd">     <!-- ... -->     <framework:config secret="%secret%">
        <framework:router resource="%kernel.root_dir%/config/routing.xml" />
        <!-- ... -->
    </framework:config>     <!-- Twig Configuration -->
    <twig:config debug="%kernel.debug%" strict-variables="%kernel.debug%" />     <!-- ... --></container>
PHP:// app/config/config.php// ... $container->loadFromExtension('framework', array(
    'secret' => '%secret%',
    'router' => array(
        'resource' => '%kernel.root_dir%/config/routing.php',
    ),
    // ...)); // Twig Configuration$container->loadFromExtension('twig', array(
    'debug'            => '%kernel.debug%',
    'strict_variables' => '%kernel.debug%',)); // ...

frameworkRoot key configuration It is FrameworkBundle, twigThe root key is configured with TwigBundle, and so on. Many in Symfony Behavior can be controlled by changing some options in the configuration file. To find out why, read Configuration Reference.

Or, use the super easy-to-use bin/console command to get one The complete configuration template stripped out under the root key:

$  php bin/console config:dump-reference framework

The Symfony configuration system is extremely powerful, including environment, imports and parameters. To get a handle on all of this, refer to the Configuration## chapter.

Next step?

congratulations! You've begun to master Symfony and will learn new ways to build beautiful, functional, fast, and maintainable programs.

Okay, you still need to be familiar with the following chapters to complete the mastery of the infrastructure:

  • Controller

  • ##Route

  • Create and use templates

Then, in Chinese book, and also learnService container, Form system, using Doctrine (if you need to query the database) and more!

There is also a Chinese cookbook##, packed with more advanced "how to" articles to solve More questions.

#I wish you all a happy study!