《PHP實(shí)戰(zhàn):Symfony2學(xué)習(xí)筆記之系統(tǒng)路由詳解》要點(diǎn):
本文介紹了PHP實(shí)戰(zhàn):Symfony2學(xué)習(xí)筆記之系統(tǒng)路由詳解,希望對您有用。如果有疑問,可以聯(lián)系我們。
PHP實(shí)戰(zhàn)本文詳細(xì)講述了Symfony2的系統(tǒng)路由.分享給大家供大家參考,具體如下:
PHP實(shí)戰(zhàn)漂亮的URL絕對是一個嚴(yán)肅的web應(yīng)用程序必須做到的,這種方式使index.php?article_id=57這類的丑陋URL被暗藏,由更受歡迎的像 /read/intro-to-symfony 來替代.
PHP實(shí)戰(zhàn)擁有靈活性更為重要,如果你要改變一個頁面的URL,比如從/blog 到 /new 怎么辦?
PHP實(shí)戰(zhàn)有多少鏈接需要你找出來并更新呢? 如果你使用Symfony的router,這種改變將變得很簡單.
PHP實(shí)戰(zhàn)Symfony2 router讓你定義更具創(chuàng)造力的URL,你可以map你的應(yīng)用程序的不同區(qū)域.
PHP實(shí)戰(zhàn)創(chuàng)建復(fù)雜的路由并map到controllers并可以在模板和controllers內(nèi)部生成URLs
PHP實(shí)戰(zhàn)從bundles(或者其他任何地方)加載路由資源
PHP實(shí)戰(zhàn)調(diào)試你的路由
PHP實(shí)戰(zhàn)路由活動
PHP實(shí)戰(zhàn)一個路徑是一個從URL 模式到一個controller的綁定.
PHP實(shí)戰(zhàn)比如假設(shè)你想匹配任何像 /blog/my-post 或者 /blog/all-about-symfony的路徑并把它們發(fā)送到一個controller在那里可以查找并渲染blog實(shí)體.
PHP實(shí)戰(zhàn)該路徑很簡單:
PHP實(shí)戰(zhàn)YAML格式:
PHP實(shí)戰(zhàn)
# app/config/routing.yml
blog_show:
pattern: /blog/{slug}
defaults: {_controller: AcmeBlogBundle:Blog:show }
PHP實(shí)戰(zhàn)XML格式:
PHP實(shí)戰(zhàn)
<!-- 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="blog_show" pattern="/blog/{slug}">
<default key="_controller">AcmeBlogBundle:Blog:show</default>
</route>
</routes>
PHP實(shí)戰(zhàn)PHP代碼格式:
PHP實(shí)戰(zhàn)
// app/config/routing.php
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;
$collection = new RouteCollection();
$collection->add('blog_show', new Route('/blog/{slug}', array(
'_controller' => 'AcmeBlogBundle:Blog:show',
)));
PHP實(shí)戰(zhàn)blog_show路徑定義了一個URL模式,它像/blog/* 這里的通配符被命名為slug.對于URL/blog/my-blog-post,slug變量會得到值 my-blog-post.
_controller參數(shù)是一個特定的鍵,它告訴Symfogy當(dāng)一個URL匹配這個路徑時哪個controller將要被執(zhí)行.
_controller字符串被稱為邏輯名.它的值會依照特定的模式來指定具體的PHP類和方法.
PHP實(shí)戰(zhàn)
// src/Acme/BlogBundle/Controller/BlogController.php
namespace Acme\BlogBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class BlogController extends Controller
{
public function showAction($slug)
{
$blog = // use the $slug variable to query the database
return $this->render('AcmeBlogBundle:Blog:show.html.twig', array(
'blog' => $blog,
));
}
}
PHP實(shí)戰(zhàn)現(xiàn)在當(dāng)你再拜訪/blog/my-post 時,showAction controller將被執(zhí)行并且$slug變量的值為my-post
PHP實(shí)戰(zhàn)Symfogy2 的路由器目標(biāo):映射一個哀求的URL到controller.
PHP實(shí)戰(zhàn)路由:內(nèi)部的秘密
PHP實(shí)戰(zhàn)當(dāng)一個哀求發(fā)送到應(yīng)用程序時,它包含一個客戶端想要獲取資源的地址.這個地址叫做URL或者URI.可能是/contact,/blog/read-me或者其它樣式.
PHP實(shí)戰(zhàn)GET /blog/my-blog-post
PHP實(shí)戰(zhàn)Symfony2 路由系統(tǒng)的目標(biāo)是解析這些URL并決定哪個controller應(yīng)該被執(zhí)行來回復(fù)該哀求.
PHP實(shí)戰(zhàn)整個路由過程可以分為:
PHP實(shí)戰(zhàn)1.哀求被Symfony2的前端控制器(app.php)處理.
2.Symfony2核心(kernel)要求路由器檢查哀求.
3.路由器匹配接收到的URL到一個特定的路徑并返回有關(guān)信息,包括應(yīng)該被執(zhí)行的controller.
4.Symfony2核心執(zhí)行該controller,該controller最終會返回一個Response對象.
PHP實(shí)戰(zhàn)路由器層就是一個把接收到的URL轉(zhuǎn)換為要執(zhí)行的特定controller的工具.
PHP實(shí)戰(zhàn)創(chuàng)建路由
PHP實(shí)戰(zhàn)Symfony會從一個單獨(dú)的路由配置文件中加載你應(yīng)用程序的所有路由.該文件通常為 app/config/routing.yml. 它可以被配置成包括XML或者PHP文件等文件.
PHP實(shí)戰(zhàn)YAML格式:
PHP實(shí)戰(zhàn)
# app/config/config.yml
framework:
# ...
router: { resource: "%kernel.root_dir%/config/routing.yml" }
PHP實(shí)戰(zhàn)XML格式:
PHP實(shí)戰(zhàn)
<!-- app/config/config.xml -->
<framework:config ...>
<!-- ... -->
<framework:router resource="%kernel.root_dir%/config/routing.xml" />
</framework:config>
PHP實(shí)戰(zhàn)PHP代碼格式:
PHP實(shí)戰(zhàn)
// app/config/config.php
$container->loadFromExtension('framework', array(
// ...
'router' => array('resource' => '%kernel.root_dir%/config/routing.php'),
));
PHP實(shí)戰(zhàn)基礎(chǔ)路由配置
PHP實(shí)戰(zhàn)定義一個路由很簡單,通常一個應(yīng)用程序擁有很多路由.一個基礎(chǔ)路由是由兩部分組成:pattern部分和defaults數(shù)組部分.
比如:
PHP實(shí)戰(zhàn)YAML格式:
PHP實(shí)戰(zhàn)
_welcome:
pattern: /
defaults: { _controller: AcmeDemoBundle:Main:homepage }
PHP實(shí)戰(zhàn)XML格式:
PHP實(shí)戰(zhàn)
<?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="_welcome" pattern="/">
<default key="_controller">AcmeDemoBundle:Main:homepage</default>
</route>
</routes>
PHP實(shí)戰(zhàn)PHP代碼格式:
PHP實(shí)戰(zhàn)
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;
$collection = new RouteCollection();
$collection->add('_welcome', new Route('/', array(
'_controller' => 'AcmeDemoBundle:Main:homepage',
)));
return $collection;
PHP實(shí)戰(zhàn)該路由匹配首頁(/)并映射到AcmeDemoBundle:Main:homepage controller._controller字符串被Symfony2翻譯成一個相應(yīng)的PHP函數(shù)并被執(zhí)行.
PHP實(shí)戰(zhàn)帶占位符路由
PHP實(shí)戰(zhàn)當(dāng)然,路由系統(tǒng)支持更多有趣的路由.許多路由會包含一個或者多個被命名的通配符占位符.
PHP實(shí)戰(zhàn)YAML格式:
PHP實(shí)戰(zhàn)
blog_show:
pattern: /blog/{slug}
defaults: { _controller: AcmeBlogBundle:Blog:show }
PHP實(shí)戰(zhàn)XML格式:
PHP實(shí)戰(zhàn)
<?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="blog_show" pattern="/blog/{slug}">
<default key="_controller">AcmeBlogBundle:Blog:show</default>
</route>
</routes>
PHP實(shí)戰(zhàn)PHP代碼格式:
PHP實(shí)戰(zhàn)
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;
$collection = new RouteCollection();
$collection->add('blog_show', new Route('/blog/{slug}', array(
'_controller' => 'AcmeBlogBundle:Blog:show',
)));
return $collection;
PHP實(shí)戰(zhàn)該模式將匹配任何類似/blog/*形式的URL.匹配占位符{slug}的值將會在controller中被使用.換句話說,如果URL是/blog/hello-world,則$slug變量值是hello-world, 該值將能在controller中被使用.該模式不會匹配像/blog, 因?yàn)槟J(rèn)情況下所有的占位符都是必須的. 當(dāng)然可以通過在defaults數(shù)組中給這些占位符賦來改變它.
PHP實(shí)戰(zhàn)必需和可選占位符
PHP實(shí)戰(zhàn)我們來添加一個新的路由,顯示所有可用的blog列表.
PHP實(shí)戰(zhàn)YAML格式:
PHP實(shí)戰(zhàn)
blog:
pattern: /blog
defaults: { _controller: AcmeBlogBundle:Blog:index }
PHP實(shí)戰(zhàn)XML格式:
PHP實(shí)戰(zhàn)
<?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="blog" pattern="/blog">
<default key="_controller">AcmeBlogBundle:Blog:index</default>
</route>
</routes>
PHP實(shí)戰(zhàn)PHP代碼格式:
PHP實(shí)戰(zhàn)
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;
$collection = new RouteCollection();
$collection->add('blog', new Route('/blog', array(
'_controller' => 'AcmeBlogBundle:Blog:index',
)));
return $collection;
PHP實(shí)戰(zhàn)到目前為止,我們的路由都是非常簡單的路由模式.它們包含的非占位符將會被精確匹配.
PHP實(shí)戰(zhàn)如果你想該路由能夠支持分頁,比如讓/blog/2 顯示第二頁的blog,那就需要為之前的路由添加一個新的{page}占位符.
PHP實(shí)戰(zhàn)YAML格式:
PHP實(shí)戰(zhàn)
blog:
pattern: /blog/{page}
defaults: { _controller: AcmeBlogBundle:Blog:index }
PHP實(shí)戰(zhàn)XML格式:
PHP實(shí)戰(zhàn)
<?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="blog" pattern="/blog/{page}">
<default key="_controller">AcmeBlogBundle:Blog:index</default>
</route>
</routes>
PHP實(shí)戰(zhàn)PHP代碼格式:
PHP實(shí)戰(zhàn)
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;
$collection = new RouteCollection();
$collection->add('blog', new Route('/blog/{page}', array(
'_controller' => 'AcmeBlogBundle:Blog:index',
)));
return $collection;
PHP實(shí)戰(zhàn)跟之前的{slug}占位符一樣{page}占位符將會在你的controller內(nèi)部可用,它的值可以用于表示要顯示的blog值的頁碼.但是要清楚,因?yàn)檎嘉环J(rèn)情況下都是必需的,該路由也將不再匹配之前的/blog URL,這時候你如果還像看第一頁的話,就必須通過/blog/1 URL來拜訪了.要解決該問題,可以在該路由的defaults數(shù)組中指定{page}的默認(rèn)值.
PHP實(shí)戰(zhàn)YAML格式:
PHP實(shí)戰(zhàn)
blog:
pattern: /blog/{page}
defaults: { _controller: AcmeBlogBundle:Blog:index, page: 1 }
PHP實(shí)戰(zhàn)XML格式:
PHP實(shí)戰(zhàn)
<?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="blog" pattern="/blog/{page}">
<default key="_controller">AcmeBlogBundle:Blog:index</default>
<default key="page">1</default>
</route>
</routes>
PHP實(shí)戰(zhàn)PHP代碼格式:
PHP實(shí)戰(zhàn)
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;
$collection = new RouteCollection();
$collection->add('blog', new Route('/blog/{page}', array(
'_controller' => 'AcmeBlogBundle:Blog:index',
'page' => 1,
)));
return $collection;
PHP實(shí)戰(zhàn)通過添加page到defaults鍵, {page}占位符就不再是必需的.這時候 /blog將會被匹配并且page參數(shù)被設(shè)置為1,URL /blog/2 也會被匹配.
PHP實(shí)戰(zhàn)添加要求約束
PHP實(shí)戰(zhàn)看看下面這些路由:
PHP實(shí)戰(zhàn)YAML格式:
PHP實(shí)戰(zhàn)
blog:
pattern: /blog/{page}
defaults: { _controller: AcmeBlogBundle:Blog:index, page: 1 }
blog_show:
pattern: /blog/{slug}
defaults: { _controller: AcmeBlogBundle:Blog:show }
PHP實(shí)戰(zhàn)XML格式:
PHP實(shí)戰(zhàn)
<?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="blog" pattern="/blog/{page}">
<default key="_controller">AcmeBlogBundle:Blog:index</default>
<default key="page">1</default>
</route>
<route id="blog_show" pattern="/blog/{slug}">
<default key="_controller">AcmeBlogBundle:Blog:show</default>
</route>
</routes>
PHP實(shí)戰(zhàn)PHP代碼格式:
PHP實(shí)戰(zhàn)
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;
$collection = new RouteCollection();
$collection->add('blog', new Route('/blog/{page}', array(
'_controller' => 'AcmeBlogBundle:Blog:index',
'page' => 1,
)));
$collection->add('blog_show', new Route('/blog/{show}', array(
'_controller' => 'AcmeBlogBundle:Blog:show',
)));
return $collection;
PHP實(shí)戰(zhàn)你發(fā)現(xiàn)問題了嗎?注意這兩個路由都能匹配像/blog/* 類型的URL.Symfony只會選擇第一個與之匹配的路由.
PHP實(shí)戰(zhàn)換句話說,blog_show將永遠(yuǎn)不會被像/blog/* 類型的URL匹配.而像 /blog/my-blog-post這樣的URL也會被blog路由匹配,并且page變量會獲得my-blog-post這樣的值.
PHP實(shí)戰(zhàn)這肯定不可以,那么怎么辦呢?答案是給路由添加約束要求requirements.
PHP實(shí)戰(zhàn)在blog路由中占位符{page}理想狀態(tài)下只匹配整數(shù)值.幸運(yùn)的是正則表達(dá)可以很容易的滿足這一要求.
PHP實(shí)戰(zhàn)YAML格式:
PHP實(shí)戰(zhàn)
blog:
pattern: /blog/{page}
defaults: { _controller: AcmeBlogBundle:Blog:index, page: 1 }
requirements:
page: \d+
PHP實(shí)戰(zhàn)XML格式:
PHP實(shí)戰(zhàn)
<?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="blog" pattern="/blog/{page}">
<default key="_controller">AcmeBlogBundle:Blog:index</default>
<default key="page">1</default>
<requirement key="page">\d+</requirement>
</route>
</routes>
PHP實(shí)戰(zhàn)PHP代碼格式:
PHP實(shí)戰(zhàn)
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;
$collection = new RouteCollection();
$collection->add('blog', new Route('/blog/{page}', array(
'_controller' => 'AcmeBlogBundle:Blog:index',
'page' => 1,
), array(
'page' => '\d+',
)));
return $collection;
PHP實(shí)戰(zhàn)這里 \d+ 約束是一個正則表達(dá)式,它指定了{(lán)page}只接受整數(shù).這樣像/blog/my-blog-post就不再被匹配了.這時候,它才會被blog_show路由匹配.因?yàn)閰?shù)的約束都是正則表達(dá)式,所以其復(fù)雜程度和靈活性都有你來決定了.
假設(shè)home頁使用兩種語言則可以這樣配置路由:
PHP實(shí)戰(zhàn)YAML格式:
PHP實(shí)戰(zhàn)
homepage:
pattern: /{culture}
defaults: { _controller: AcmeDemoBundle:Main:homepage, culture: en }
requirements:
culture: en|fr
PHP實(shí)戰(zhàn)XML格式:
PHP實(shí)戰(zhàn)
<?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="homepage" pattern="/{culture}">
<default key="_controller">AcmeDemoBundle:Main:homepage</default>
<default key="culture">en</default>
<requirement key="culture">en|fr</requirement>
</route>
</routes>
PHP實(shí)戰(zhàn)PHP代碼格式:
PHP實(shí)戰(zhàn)
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;
$collection = new RouteCollection();
$collection->add('homepage', new Route('/{culture}', array(
'_controller' => 'AcmeDemoBundle:Main:homepage',
'culture' => 'en',
), array(
'culture' => 'en|fr',
)));
return $collection;
PHP實(shí)戰(zhàn)添加HTTP 辦法約束
PHP實(shí)戰(zhàn)除了URL,你還可以匹配哀求的方法(GET,HEAD,POST,PUT,DELETE等).假設(shè)你有一個聯(lián)系表單有兩個controller,一個用于顯示表單(使用GET哀求)一個用于處理提交的表單(POST哀求).它的配置如下:
PHP實(shí)戰(zhàn)YAML格式:
PHP實(shí)戰(zhàn)
contact:
pattern: /contact
defaults: { _controller: AcmeDemoBundle:Main:contact }
requirements:
_method: GET
contact_process:
pattern: /contact
defaults: { _controller: AcmeDemoBundle:Main:contactProcess }
requirements:
_method: POST
PHP實(shí)戰(zhàn)XML格式:
PHP實(shí)戰(zhàn)
<?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="contact" pattern="/contact">
<default key="_controller">AcmeDemoBundle:Main:contact</default>
<requirement key="_method">GET</requirement>
</route>
<route id="contact_process" pattern="/contact">
<default key="_controller">AcmeDemoBundle:Main:contactProcess</default>
<requirement key="_method">POST</requirement>
</route>
</routes>
PHP實(shí)戰(zhàn)PHP代碼格式:
PHP實(shí)戰(zhàn)
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;
$collection = new RouteCollection();
$collection->add('contact', new Route('/contact', array(
'_controller' => 'AcmeDemoBundle:Main:contact',
), array(
'_method' => 'GET',
)));
$collection->add('contact_process', new Route('/contact', array(
'_controller' => 'AcmeDemoBundle:Main:contactProcess',
), array(
'_method' => 'POST',
)));
return $collection;
PHP實(shí)戰(zhàn)盡管這兩個路由擁有同一個URL模式定義(/contact),但是第一個路由只會匹配GET哀求,而第二個只會匹配POST哀求.這就意味著你可以通過同一個URL來顯示表單并提交表單,而用不同的controller對他們進(jìn)行處理.如果沒有指定_method約束,那么該路由會匹配所有哀求方法.跟其它約束一樣,_method約束也接受正則表達(dá)式,如果只想匹配GET或者POST那么你可以用GET|POST
PHP實(shí)戰(zhàn)高級路由例子:
PHP實(shí)戰(zhàn)Symfony2中具備一切讓你創(chuàng)建任何形式路由的條件.
PHP實(shí)戰(zhàn)YAML格式:
PHP實(shí)戰(zhàn)
article_show:
pattern: /articles/{culture}/{year}/{title}.{_format}
defaults: { _controller: AcmeDemoBundle:Article:show, _format: html }
requirements:
culture: en|fr
_format: html|rss
year: \d+
PHP實(shí)戰(zhàn)XML格式:
PHP實(shí)戰(zhàn)
<?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="article_show" pattern="/articles/{culture}/{year}/{title}.{_format}">
<default key="_controller">AcmeDemoBundle:Article:show</default>
<default key="_format">html</default>
<requirement key="culture">en|fr</requirement>
<requirement key="_format">html|rss</requirement>
<requirement key="year">\d+</requirement>
</route>
</routes>
PHP實(shí)戰(zhàn)PHP代碼格式:
PHP實(shí)戰(zhàn)
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;
$collection = new RouteCollection();
$collection->add('homepage', new Route('/articles/{culture}/{year}/{title}.{_format}', array(
'_controller' => 'AcmeDemoBundle:Article:show',
'_format' => 'html',
), array(
'culture' => 'en|fr',
'_format' => 'html|rss',
'year' => '\d+',
)));
return $collection;
PHP實(shí)戰(zhàn)上面的路由,在匹配時只會匹配{culture}部分值為en或者fr并且{year}的值為數(shù)字的URL.該路由還告訴我們,可以用在占位符之間使用區(qū)間代替斜線.
PHP實(shí)戰(zhàn)它能夠匹配如下URL:
PHP實(shí)戰(zhàn)/articles/en/2010/my-post
/articles/fr/2010/my-post.rss
PHP實(shí)戰(zhàn)這其中有個特殊的路由參數(shù) _format,在使用該參數(shù)時,其值變?yōu)榘蟾袷?這種哀求格式相當(dāng)于Respose對象的Content-Type,比如json哀求格式會翻譯成一個Content-Type為application/json.該參數(shù)可以用于在controller中為每個_format渲染一個不同的模板.它是一個很強(qiáng)的方式來渲染同一個內(nèi)容到不同的格式.
PHP實(shí)戰(zhàn)特殊的路由參數(shù):
PHP實(shí)戰(zhàn)正如你所看到的,每一個路由參數(shù)或者默認(rèn)值最終都是作為一個controller辦法輸入?yún)?shù)被使用.另外,有三個參數(shù)比較特別,它們每一個都在你的應(yīng)用程序中增加一個唯一功能.
PHP實(shí)戰(zhàn)_controller: 這個參數(shù)決定了當(dāng)路由匹配時,哪個controller被執(zhí)行.
_format: 用于設(shè)置哀求格式.
_locale: 用于在session上設(shè)置本地化.
PHP實(shí)戰(zhàn)Controller的命名模式:
PHP實(shí)戰(zhàn)每一個路由必須有一個_controller參數(shù),它決定了當(dāng)路由匹配時哪個controller應(yīng)該被執(zhí)行.該參數(shù)使用單一的字符串模式,被稱為logical controller name.
PHP實(shí)戰(zhàn)通過它Symfony可以映射到一個特定的PHP辦法和類.該模式有三部分,每一部分用冒號分割開:
PHP實(shí)戰(zhàn)
bundle:controller:action
PHP實(shí)戰(zhàn)比如_controller 的值為 AcmeBlogBundle:Blog:show 意思是AcmeBlogBundle bundle中BlogController類里面的showAction辦法.
PHP實(shí)戰(zhàn)
// src/Acme/BlogBundle/Controller/BlogController.php
namespace Acme\BlogBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class BlogController extends Controller
{
public function showAction($slug)
{
// ...
}
}
PHP實(shí)戰(zhàn)Symfony會自動把它們的添加相應(yīng)的后綴,Blog=>BlogController, show => showAction.
PHP實(shí)戰(zhàn)你也可以使用它的完全限定名和辦法來給_controller賦值,Acme\BlogBundle\Controller\BlogController::showAction 但一般為了簡潔靈活而是用邏輯名稱.另外除了上面兩種形式外,Symfony還支持第三種方式只有一個冒號分割符,如service_name:indexAction來為_controller賦一個作為服務(wù)使用的controller.
PHP實(shí)戰(zhàn)路由參數(shù)和控制器參數(shù)
PHP實(shí)戰(zhàn)路由參數(shù)非常重要,因?yàn)槊恳粋€路由參數(shù)都會轉(zhuǎn)變成一個控制器參數(shù)被在辦法中使用.
PHP實(shí)戰(zhàn)
public function showAction($slug)
{
// ...
}
PHP實(shí)戰(zhàn)事實(shí)上,全部的defaults集合和表單的參數(shù)值合并到一個單獨(dú)的數(shù)組中.這個數(shù)組中的每個鍵都會成為controller辦法的參數(shù).換句話說,你的controller辦法的每一個參數(shù),Symfony都會從路由參數(shù)中查找并把找到的值賦給給參數(shù).上面例子中的變量 $culture, $year,$title,$_format,$_controller 都會作為showAction()辦法的參數(shù).因?yàn)檎嘉环蚫efaults集合被合并到一起,即使$_controller變量也是一樣.你也可以使用一個特殊的變量$_route 來指定路由的名稱.
PHP實(shí)戰(zhàn)包括外部路由資源
PHP實(shí)戰(zhàn)所有的路由資源的都是通過一個單一的配置文件導(dǎo)入的.通常是app/config/routing.yml.當(dāng)然你可能想從別處導(dǎo)入路由資源,比如你定義的bundle中的路由資源,你可以這樣導(dǎo)入:
PHP實(shí)戰(zhàn)YAML格式:
PHP實(shí)戰(zhàn)
# app/config/routing.yml
acme_hello:
resource: "@AcmeHelloBundle/Resources/config/routing.yml"
PHP實(shí)戰(zhàn)XML格式:
PHP實(shí)戰(zhàn)
<!-- 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">
<import resource="@AcmeHelloBundle/Resources/config/routing.xml" />
</routes>
PHP實(shí)戰(zhàn)PHP代碼格式:
PHP實(shí)戰(zhàn)
// app/config/routing.php
use Symfony\Component\Routing\RouteCollection;
$collection = new RouteCollection();
$collection->addCollection($loader->import("@AcmeHelloBundle/Resources/config/routing.php"));
return $collection;
PHP實(shí)戰(zhàn)在使用YAML導(dǎo)入資源時,鍵(比如acme_hello)是沒有意義的,只是用來保證該資源唯一不被其它行覆蓋.使用resources key加載給定的路由資源.在這個示例中資源是一個全路徑文件,@AcmeHelloBundle是簡寫語法,它會被指向bundle路徑.被導(dǎo)入的文件內(nèi)容如下:
PHP實(shí)戰(zhàn)YAML格式:
PHP實(shí)戰(zhàn)
# src/Acme/HelloBundle/Resources/config/routing.yml
acme_hello:
pattern: /hello/{name}
defaults: { _controller: AcmeHelloBundle:Hello:index }
PHP實(shí)戰(zhàn)XML格式:
PHP實(shí)戰(zhàn)
<!-- src/Acme/HelloBundle/Resources/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="acme_hello" pattern="/hello/{name}">
<default key="_controller">AcmeHelloBundle:Hello:index</default>
</route>
</routes>
PHP實(shí)戰(zhàn)PHP代碼格式:
PHP實(shí)戰(zhàn)
// src/Acme/HelloBundle/Resources/config/routing.php
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;
$collection = new RouteCollection();
$collection->add('acme_hello', new Route('/hello/{name}', array(
'_controller' => 'AcmeHelloBundle:Hello:index',
)));
return $collection;
PHP實(shí)戰(zhàn)這個文件中的路由會被解析并跟主要的路由文件內(nèi)容一起被加載.
PHP實(shí)戰(zhàn)給導(dǎo)入的路由資源添加前綴
PHP實(shí)戰(zhàn)你可以為導(dǎo)入的路由資源選擇一個前綴,比如說假設(shè)你想acme_hello路由有一個這樣的 匹配模式:/admin/hello/{name} 而不是直接的 /hello/{name}
PHP實(shí)戰(zhàn)那么你在導(dǎo)入它的時候可以為其指定prefix.
PHP實(shí)戰(zhàn)YAML格式:
PHP實(shí)戰(zhàn)
# app/config/routing.yml
acme_hello:
resource: "@AcmeHelloBundle/Resources/config/routing.yml"
prefix: /admin
PHP實(shí)戰(zhàn)XML格式:
PHP實(shí)戰(zhàn)
<!-- 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">
<import resource="@AcmeHelloBundle/Resources/config/routing.xml" prefix="/admin" />
</routes>
PHP實(shí)戰(zhàn)PHP代碼格式:
PHP實(shí)戰(zhàn)
// app/config/routing.php
use Symfony\Component\Routing\RouteCollection;
$collection = new RouteCollection();
$collection->addCollection($loader->import("@AcmeHelloBundle/Resources/config/routing.php"), '/admin');
return $collection;
PHP實(shí)戰(zhàn)當(dāng)該外部路由資源加載的時候字符串 /admin 將被插入到匹配模式的前面.
PHP實(shí)戰(zhàn)可視化并調(diào)試路由
PHP實(shí)戰(zhàn)當(dāng)你添加和個性化路由時,能夠看到它并能獲取一些細(xì)節(jié)信息將是非常有用的.一個好的查看你應(yīng)用程序的路由的辦法是通過router:debug 命令行工具.
PHP實(shí)戰(zhàn)在你項目目錄下執(zhí)行如下命令:
PHP實(shí)戰(zhàn)
$ php app/console router:debug
PHP實(shí)戰(zhàn)將會輸出你應(yīng)用程序的所有路由.你也可以在該命令后面添加某個路由的名字來獲取單個路由信息
PHP實(shí)戰(zhàn)
$ php app/console router:debug article_show
PHP實(shí)戰(zhàn)生成URL
PHP實(shí)戰(zhàn)一個路由系統(tǒng)應(yīng)該也能用來生成URL.事實(shí)上,路由系統(tǒng)是一個雙向的系統(tǒng),映射URL到controller+parameters 和 回對應(yīng)到 一個URL.可以使用match()和generate()辦法來操作.比如:
PHP實(shí)戰(zhàn)
$params = $router->match('/blog/my-blog-post');
// array('slug' => 'my-blog-post', '_controller' => 'AcmeBlogBundle:Blog:show')
$uri = $router->generate('blog_show', array('slug' => 'my-blog-post'));
// /blog/my-blog-post
PHP實(shí)戰(zhàn)要生成一個URL,你需要指定路由的名稱(比如 blog_show)和任意的通配符(比如:slug=my-blog-post)作為參數(shù).通過這些信息,可以生成任意的URL.
PHP實(shí)戰(zhàn)
class MainController extends Controller
{
public function showAction($slug)
{
// ...
$url = $this->get('router')->generate('blog_show', array('slug' => 'my-blog-post'));
}
}
PHP實(shí)戰(zhàn)那么如何從模板內(nèi)部來生成URL呢?如果你的應(yīng)用程序前端使用了AJAX哀求,你也許想能夠基于你的路由配置在javascript中生成URL,通過使用
PHP實(shí)戰(zhàn)FOSJsRoutingBundle(https://github.com/FriendsOfSymfony/FOSJsRoutingBundle) 你可以做到:
PHP實(shí)戰(zhàn)
var url = Routing.generate('blog_show', { "slug": 'my-blog-post'});
PHP實(shí)戰(zhàn)生成絕對路徑的URL
PHP實(shí)戰(zhàn)默認(rèn)的情況下,路由器生成相對路徑的URL(比如 /blog).要生成一個絕對路徑的URL,只需要傳入一個true到generate辦法作為第三個參數(shù)值即可.
PHP實(shí)戰(zhàn)
$router->generate('blog_show', array('slug' => 'my-blog-post'), true);
// http://www.example.com/blog/my-blog-post
PHP實(shí)戰(zhàn)當(dāng)生成一個絕對路徑URL時主機(jī)是當(dāng)前哀求對象的主機(jī),這個是基于PHP提供的服務(wù)器信息自動決定的.當(dāng)你需要為運(yùn)行子命令行的腳本生成一個絕對URL時,你需要在Request對象上手動設(shè)置期望的主機(jī)頭.
PHP實(shí)戰(zhàn)
$request->headers->set('HOST', 'www.example.com');
PHP實(shí)戰(zhàn)生成帶有查詢字符串的URL
PHP實(shí)戰(zhàn)generate()帶有一個數(shù)組通配符值來生成URI. 但是如果你傳入額外的值,它將被添加到URI作為查詢字符串:
PHP實(shí)戰(zhàn)
$router->generate('blog', array('page' => 2, 'category' => 'Symfony'));
// /blog/2?category=Symfony
PHP實(shí)戰(zhàn)從模板中生成URL
PHP實(shí)戰(zhàn)最常用到生成URL的地方是從模板中鏈接兩個頁面時,這來需要使用一個模板贊助函數(shù):
PHP實(shí)戰(zhàn)Twig格式:
PHP實(shí)戰(zhàn)
<a href="{{ path('blog_show', { 'slug': 'my-blog-post' }) }}">
Read this blog post.
</a>
PHP實(shí)戰(zhàn)PHP格式:
PHP實(shí)戰(zhàn)
<a href="<?php echo $view['router']->generate('blog_show', array('slug' => 'my-blog-post')) ?>">
Read this blog post.
</a>
PHP實(shí)戰(zhàn)也可以生成絕對路徑:
PHP實(shí)戰(zhàn)Twig格式:
PHP實(shí)戰(zhàn)
<a href="{{ url('blog_show', { 'slug': 'my-blog-post' }) }}">
Read this blog post.
</a>
PHP實(shí)戰(zhàn)PHP格式:
PHP實(shí)戰(zhàn)
<a href="<?php echo $view['router']->generate('blog_show', array('slug' => 'my-blog-post'), true) ?>">
Read this blog post.
</a>
PHP實(shí)戰(zhàn)強(qiáng)制路由使用HTTPS或者HTTP
PHP實(shí)戰(zhàn)有時候?yàn)榱似桨财鹨?你需要你的站點(diǎn)必須使用HTTPS協(xié)議訪問.這時候路由組件可以通過_scheme 約束來強(qiáng)迫URI方案.比如:
PHP實(shí)戰(zhàn)YAML格式:
PHP實(shí)戰(zhàn)
secure:
pattern: /secure
defaults: { _controller: AcmeDemoBundle:Main:secure }
requirements:
_scheme: https
PHP實(shí)戰(zhàn)XML格式:
PHP實(shí)戰(zhàn)
<?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="secure" pattern="/secure">
<default key="_controller">AcmeDemoBundle:Main:secure</default>
<requirement key="_scheme">https</requirement>
</route>
</routes>
PHP實(shí)戰(zhàn)PHP代碼格式:
PHP實(shí)戰(zhàn)
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;
$collection = new RouteCollection();
$collection->add('secure', new Route('/secure', array(
'_controller' => 'AcmeDemoBundle:Main:secure',
), array(
'_scheme' => 'https',
)));
return $collection;
PHP實(shí)戰(zhàn)上面的路由定義就是強(qiáng)迫secure路由使用HTTPS協(xié)議拜訪.
PHP實(shí)戰(zhàn)反之,當(dāng)生成secure 的URL的時候,路由系統(tǒng)會根據(jù)當(dāng)前的拜訪協(xié)議方案生成相應(yīng)的拜訪協(xié)議.比如當(dāng)前是HTTP,則會自動生成HTTPS拜訪;如果是HTTPS拜訪,那么就也會相應(yīng)的生成HTTPS拜訪.
PHP實(shí)戰(zhàn)
# 如果方案是 HTTPS
{{ path('secure') }}
# 生成 /secure
# 如果方案是 HTTP
{{ path('secure') }}
# 生成 https://example.com/secure
PHP實(shí)戰(zhàn)當(dāng)然你也可以通過設(shè)置_scheme為HTTP,來強(qiáng)制使用HTTP拜訪協(xié)議.除了上面說的強(qiáng)迫使用HTTPS協(xié)議拜訪的設(shè)置方法外,還有一種用于站點(diǎn)區(qū)域設(shè)置
PHP實(shí)戰(zhàn)使用requires_channel 比如你想讓你站點(diǎn)中/admin 下面的所有路由都必須使用HTTPS協(xié)議訪問,或者你的平安路由定義在第三方bundle時使用.
PHP實(shí)戰(zhàn)總結(jié):
PHP實(shí)戰(zhàn)路由系統(tǒng)是一個為將接收的哀求URL映射到被調(diào)用來處理該哀求的controller函數(shù)的系統(tǒng).它既能夠讓你生成漂亮的URL同時又能保持你的應(yīng)用程序功能跟這些URL解耦.路由系統(tǒng)是雙向機(jī)制的,也就是說它們也可以用來生成URL.
PHP實(shí)戰(zhàn)希望本文所述對大家基于Symfony框架的PHP程序設(shè)計有所贊助.
維易PHP培訓(xùn)學(xué)院每天發(fā)布《PHP實(shí)戰(zhàn):Symfony2學(xué)習(xí)筆記之系統(tǒng)路由詳解》等實(shí)戰(zhàn)技能,PHP、MYSQL、LINUX、APP、JS,CSS全面培養(yǎng)人才。
轉(zhuǎn)載請注明本頁網(wǎng)址:
http://www.fzlkiss.com/jiaocheng/7333.html