創建你的第一個Symfony頁面


建立一個新頁面- 無論是HTML或JSON輸出- 都是一個簡單的「兩個步驟」操作:

  1. ##建立一個路由:路由(route)是一個指向你的頁面URL(例如/about),同時映射到一個控制器。

  2. 建立一個控制器##:控制器( controller)是你為了構造頁面而寫的功能。你要拿到傳送來的請求請求訊息,用它建立一個Symfony的Response對象,令其包含HTML內容,JSON字串或是其他

如同在網路上每一次互動都是從HTTP請求開始,你的任務單純而簡單:理解請求,回傳回應。

建立一個頁面:路由與控制器 

在開始之前,確保你已經閱讀了安裝和設定Symfony 章節,同時已經可以存取瀏覽器中的Symfony程式。

假設你要新一個/lucky/number頁面,用於產生一個隨機的幸運數字並且輸出它。那麼,要先建立一個類別並新增方法,用於在某人存取/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>'
        );
    }}


#在開始之前測試一下

http:// localhost:8000 / lucky / number

##如果你在

Apache或Nginx#上正確設定了虛擬主機,就可以把http:// localhost:8000部分替換為自己的主機名,例如http://symfony.dev/app_dev.php/lucky/number#

如果你看到一個幸運數字被輸出,那麼恭喜你!不過在玩樂透之前,先了解它是如何運作的。

numberAction@Route 被稱為註解#,它定義了URL符合。你也可以在YAML(或其他格式)寫路由:請參考路由##章節。實際上,文件中的多數路由例程都有“標籤”,以顯示每種格式的配置

註解下面的方法- numberAction- 被稱為控制器,這是你控制頁面的地方。這個唯一的原則是:一個控制器必須回傳一個Symfony的 回應物件(你最終將學習到活用這個原則)。

建立一個JSON回應 

在控制器中傳回的Response物件可以包含HTML,JSON甚至二進位檔案例如圖片或PDF。你可以輕鬆設定HTTP頭資訊或HTTP狀態碼。


假設你要建立一個JSON回傳值,則只需要##LuckyController

再新增一個方法:

  // 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')
        );
    }}
   

#在瀏覽器中測試


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

##你更可將程式碼精簡為超好用的JsonResponse

// 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);
    }}

# ##############動態URL符合:/ lucky / number / {count}  ###############¶######### #############窩,你做得很好但Symfony的路由還可以做得更多假設你希望用戶可以到###​​####! #########/lucky/number/5#########來立即產生幸運數字5,更新路由,在使其擁有尾部一個#########{ 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;

因為{count}佔位符,頁面URL變成不一樣了。現在它要求URL匹配/lucky/number/*#,例如/lucky/number/5#。這樣一來你可以在控制器中收到並使用這個值:

// 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>'
        );
    }     // ...}

#去/lucky/number/ xx測試一下,把xx換成# 任意## 數字:

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

#你應該看到幸運數字7被輸出!在控制器中增加一個$placeholder參數,你就可以得到路由中任何一個##{placeholder}佔位符的值只要確保它們的名字相同即可。

系統-路由也可以做更多#,像是支援多個佔位符(例如/blog/{category}/{page}),令佔位符可選以及強制佔位符匹配一個正規表示式(例如

{count}必須為數字)。

#章節中尋找更多,即可成為路由專家。

渲染模板(利用容器)  ##如果你在控制器中回傳HTML,你可能需要渲染模板。幸運的是,Symfony擁有Twig:一種易學的模板語言,強大卻相當有趣。 目前,

LuckyController#沒有繼承任何基底類別。此時引用Twig(或其他Symfony工具)最簡單的方式,就是繼承Symfony的Controller##基底類別:

####
// src/AppBundle/Controller/LuckyController.php  
// ...
// --> add this new use statement
use Symfony\Bundle\FrameworkBundle\Controller\Controller; 
class LuckyController extends Controller
{    // ...}
#########使用模板服務  ############¶############

這些並不會改變任何東西,但把你帶入Symfony的#容器/容器 :這是一個數組模樣的對象,允許你從中取出系統級的#每一個##有用對象這些有用的物件稱為服務(服務) ,其中Symfony送出了一個專門用於渲染範本的服務對象,還有一個用來記錄日誌的,以及許多許多。

渲染Twig模板,要求到的服務名稱為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);
    }     // ...}


#「服務容器」十分重要,學習過程中你會掌握大量相關知識。現在,你只需了解它擁有很多對象,然後你可以通過「暱稱」(例如templatinglogger )利用get()#來得到其中的任何一個。 templating服務,是#TwigEngine的實例,裡面有個 render()方法。

但還可以再簡單一點!透過繼承Controller基類,你可以使用很多快捷方法,例如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)
        );
  }

關於控制器中的快速方法是如何運作的請參閱控制器章節。

進階使用者請參考#如何定義控制器為服務

#######

建立範本 

#如果你現在重新整理頁面,會得到一個報錯:

#無法找到範本「lucky / number.html.twig」

修復它要靠建立一個新的app/Resources/views/lucky目錄,再將number.html.twig都置於其中:

枝条:{# 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歡迎你!這個簡單的檔案已經展示了基本功能:像是{{ variableName }}語法被用來列印一些東西。而luckyNumberList這個變數就是你在控制器中的render()方法中將其傳遞進來。

% extends 'base.html.twig' %對應的是一個佈局文件,它們位於app / Resources / views / base.html.twig#,這個檔案隨Symfony專案的建立而存在。它相當地#單純(只是一個未經樣式處理的HTML結構),供你自訂。 {% block body %}部分則是使用了嫩枝模板的##繼承系統/繼承系統,將來的其間置於內容父模板base.html.twig佈局中的對應位置。

立即重新整理頁面

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

#如果你查看頁面原始碼,你會看到完整的HTML骨架,多虧了#base.html.twig

這只是Twig威力的極小部分。若你希望精通Twig的語法,數組循環,輸出其他模板甚至更多超酷功能,應該參閱創建並使用模板

瀏覽整個專案 

你已經創建了一個彈性的URL,渲染了一個「使用了繼承功能」的模板,並且輸出了JSON回應。

是時候瀏覽你的專案中的檔案並且去掉它們的神秘光環了。之前你已經在兩個極為重要的資料夾中進行作業:

#app/

內容設定檔和範本。大體上,只要不是# PHP程式碼的材質都放在這裡。


src/#

你的PHP程式之所在99%的時間你都會工作在src/(PHP檔案)或app/ (其他東東)之下。隨著你的技術實力高大上起來,你會學到每個文件夾下都發生了什麼事。

app/目錄也存在其他內容,app/AppKernel.php像是,你要用它來開啟新捆綁(它是app/#下面很少的PHP檔案之一)。

src/目錄下暫時只有一個目錄- src/AppBundle- 所有的東西都在這裡面。一個包,像一個“插件”,你可以找到開源捆綁#,然後把它們安裝到你的專案中,但就算是你自己的程式碼,也是處理束之中- 典型的就是AppBundle(儘管這捆毫無特殊之處)。為了深入了解捆綁,以及為何你應該建立多個捆綁(提示:在專案之間共用程式碼),請參閱Bundle系統章節。

那麼專案中的其他資料夾又是什麼情況呢?

web/

#它是整個專案的文檔根目錄,存在可公開訪問的文件,例如CSS,圖片以及用於執行應用程式(app_dev.phpapp.php)的Symfony的前端控制器(前端控制器)。


tests/

#你程式的自動測試(如單元測試/單元測試)被存放在這裡。


bin/

#是用來存放二進位(binary)檔案。最重要的是console文件,它被用來控制中執行Symfony指令。


var/

#這是那些自動產生的檔案被存放的地方,例如快取檔案(var/cache/)和日誌檔案(var/logs/ )。


vendor/

透過依賴管理器Composer,第三方類別庫,包,bundles被下載到這裡。你應該不去編輯這個目錄下的東西。

Symfony是彈性化的。如果需要,你可以覆寫預設的目錄結構。參考如何覆寫Symfony的預設#目錄結構

#

程式層級的設定 

#Symfony內建了幾款原生束(打開你的app/AppKernel.php#檔案檢視),你可以安裝更多.bundles的主要設定檔是 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%',)); // ...

framework##根鍵配置的是FrameworkBundle,twig根鍵配置的是TwigBundle,諸如此類.Symfony中的許多行為都可以被控制,只需改變設定檔的一些選項即可。要搞清原因,請閱讀配置參考

或者,透過超好用的#bin/console指令,取得一個根鍵下被剝離出的完整配置樣板:

$  php bin/console config:dump-reference framework

Symfony配置系統的威力絕大,包括環境,導入和參數等。為了掌握所有這些,參考配置#章節。

下一步? 

#恭喜你!你已經開始掌握Symfony,並將學到以全新方式來打造美麗的,功能性的,快速的,可維護的程序。

好了,你還需要熟悉下面這些章節,才能完成對基礎架構的掌握:

  • #控制器

  • ##建立並使用範本

#然後,在#中文書,也要學習#服務容器表單系統,使用Doctrine (如果你需要查詢資料庫的話)以及更多! #

還有一本中文食譜#,打包了更深的「如何」文章以解決更多#問題。

祝各位學得高興!