<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                # 路由 SF以及所有現代PHP框架都采用“單一入口”的方式。 所謂“單一入口”說的是,一個Web應用,不管要訪問哪個資源和URI,都統一由一個單一的入口文件進行調派。在SF中,這個文件就是`web/app.php`(生產環境)或者`web/app_dev.php`(開發環境)。 在單一入口模式下,用戶在瀏覽器中鍵入類似“`mysite/book/list`”這樣的地址的時候,這樣的請求會被入口文件處理,從中分離出不同的部分。在SF中,這樣的部分可能包括:控制器(一個類)、動作(類方法)、參數等。 怎樣來進行這個分離的動作呢?SF采用的是路由(router)的方法。 在SF中,定義路由有幾種方式。比如注釋方式(annotation)、YML、XML、PHP等。我個人比較喜歡的是用YML的方式。 ## 定義入口路徑 不管我們如何設計WEB應用,總是需要定義一個“入口”。 修改或者創建該文件?`src/AppBundle/Resources/config/routing.yml`,使之包含如下內容: ~~~ home: path: / defaults: { _controller: AppBundle:Default:index } ~~~ 同時修改`app/config/routing.yml`,使之只有如下內容: ~~~ rsywx: resource: "@AppBundle/Resources/config/routing.yml" ~~~ 修改`app/config/routing.yml`的目的是向SF應用表明,我們的路由配置將來自`src/AppBundle/Resources/config/routing.yml`文件。這個文件是一個YML格式的文件,定義了我們應用中所要提供的所有資源的路徑配置。 修改完畢后我們再次訪問應用,瀏覽器將會顯示我們之前看到的SF歡迎頁面: ![](https://box.kancloud.cn/72862c19b3b57276c6b47244ccee5628_768x543.png) ## 路徑配置 路徑配置的核心包括三個部分: 1. 路徑名。如`home`這樣的一個名稱。該名稱必須在某個路徑配置文件中唯一。 2. 路徑。如`path: /`。該路徑定義了應用能提供的URI。在本例中,我們定義的是入口,也就是通常所說的“首頁”、“主頁”。所以它的路徑是`/`。我們在WEB中用`http(s)://sitename/`對該資源進行訪問。 3. 動作。如`defaults: { _controller: AppBundle:Default:index }`。該動作表明,該路由將調用控制器的某個動作。該控制器位于`src/AppBundle/Controller/DefaultController.php`中,而調用的具體動作是`indexAction`方法。 由此,我們得到此類路徑動作的一個重要約定。SF在尋找動作的時候,會在指定的Bundle(本例中的`AppBundle`目錄,即`src/AppBundle`的控制器目錄(即`src/AppBundle/Controller`)下尋找一個名為“`類名+Controller.php`”的文件(即`DefaultController.php`),并在其中尋找一個名為“`類名+Controller`”的類(即`class DefaultContrller`),再在其中找到一個“`動作名+Action`”的公共方法(即`public function indexAction`)并加以調用。 我們略微看一些這個控制器文件: ~~~ <?php namespace AppBundle\Controller; class DefaultController extends Controller { public function indexAction(Request $request) { // replace this example code with whatever you need return $this->render('default/index.html.twig', [ 'base_dir' => realpath($this->getParameter('kernel.root_dir').'/..'), ]); } } ~~~ 我們在以后還會詳細解釋控制器的編寫。這里只是簡單地提一句:一般情況下,一個控制器中的動作都會返回一個模板的渲染,于是瀏覽器就有內容加以顯示。 ## 兩個重要的命令 在深入討論更多路由配置之前,我們先看兩個SF提供的和路由密切相關的命令。 ## 路由匹配 總有一天,我們的路由配置會越來越復雜,于是我們會產生疑惑(應用也可能產生bug):某個URI到底匹配哪個路由?其匹配的路由到底是不是我們原先設計中想要的呢? 我們可以使用`php bin/console router:match`命令來對一個URI匹配哪個路由進行調試。比如對`/`路由的調試命令為: ~~~ php bin/console router:match / ~~~ 該命令會產生如下輸出: ![](https://box.kancloud.cn/5e976e3ebb52034730b753eaea4ee77f_675x425.png) 可見,如我們的設計,`/`匹配了我們定義的`home`路由,它所調用的正是我們規定的`AppBundle:Default:index`動作。 ## 路由調試 有時,我們需要知道在應用中到底定義了多少路由,這時我們可以用如下的命令: ~~~ php bin/console debug:router ~~~ 該命令將列出所有的路徑名、調用方法(是`POST`、`GET`或者其它還是無所謂)、協議(比如是不是必須要求https)、主機(可以由哪些主機對此訪問)和路徑。 ## 更多的路由配置 我們再來看幾個路由,以了解更多的路由配置。 在這個藏書管理程序中,有一個功能是書籍列表(分頁)。該路由定義如下: ~~~ book_list: path: /books/list/{type}/{key}/{page} defaults: page: 1 type: title key: all _controller: AppBundle:Book:list ~~~ SF采用`{...}`來標記路徑中的參數。在上例的路由中,其路徑有三個參數: * `type`:確定書籍列表的類型。一種是列書名,一種是列tag(更多的說明見后續章節); * `key`:如果`type`是列書名,這里就是書名的開始部分;如果`type`是列tag,這里就是一個tag; * `page`:確定要顯示第幾頁。 因此用這樣一個單一的路徑,我們可以可以顯示三種不同的書籍列表: 1. 不帶任何參數,或者參數為缺省值,那么列出所有藏書(按照`id`降序,亦即最新登錄的書籍最先展示)的第一頁。 2. 按照書名開頭進行搜索,顯示匹配書名開頭部分的那些書籍。 3. 按照tag進行搜索,顯示匹配tag的那些書籍。 在我的網站中,這些頁面的效果如下所示[1](https://taylorr.gitbooks.io/building-a-web-site-with-symfony/content/05.06%20router.html#fn_1): ![](https://box.kancloud.cn/069f260eff328e120b203fb6d4658f27_1024x736.png)![](https://box.kancloud.cn/99fd3fa441d1ef93fc31e1c484e90f60_1024x736.png)![](https://box.kancloud.cn/79580291a8a4bae1a711e15e23f27d36_1024x736.png) 我們需要注意的是瀏覽器地址欄顯示的地址。還有就是,雖然這是三個不同的動作,但是它們使用的顯示模板是一樣的。 在該路由的配置中,其`defaults`段和之前的不同。除了按照常規要制定一個控制器和動作外,我們對該路由的路徑中出現的三個參數設置了一個缺省值。所以我們在訪問`books/list`的時候,實際上就是訪問了`/books/list/title/all/1`。 ## 只能進行`POST`訪問的路徑 該應用中還有一些路徑是用來處理表單輸入的。對于這樣的路徑,我們不希望用戶在瀏覽器中直接輸入URI而進行誤操作,所以需要對該路徑可以通過怎樣的方法進行訪問加以限制。 比如下面這個為一本書增加tag的路徑: ~~~ tags_add: path: /books/addtag defaults: {_controller: AppBundle:Book:tagsAdd} requirements: _method: POST ~~~ 這里我們設置了路由的一些額外要求。其中的`_method: POST`規定該路由只能通過`POST`方式訪問。 ## 對參數的限制 我們有一個書籍詳情的頁面,列出書籍的詳細信息。該路徑定義如下: ~~~ book_detail: path: /books/{id}.html defaults: { _controller: AppBundle:Book:detail } ~~~ 于是我們就可以用類似`/books/00005.html`這樣的方式來訪問一本書籍。但是這么做有一個小問題。 在我們的數據庫中,一本書的`bookid`有5位,按照約定,它應該都是數字并有前導0,比如`00666`,`01234`等。類似`1234`(位數不夠),`abcd8`(混雜了字母)這樣的參數是不合理的。如果用上述的這個路徑定義,我們訪問`/books/1234.html`的時候,也還會匹配到上面的那個路徑。這樣做不會有什么致命的后果,只是數據庫中無法找到這本書,顯示一個“該書籍找不到”的頁面而已[2](https://taylorr.gitbooks.io/building-a-web-site-with-symfony/content/05.06%20router.html#fn_2)。但是這樣不是很好的方法,如果我們能對路徑中參數加以限制,使得那些不符合要求的參數(和URI)根本不訪問該路由,我們至少解決了部分問題。 于是我們要對該路由中參數`id`加以限制。我們修改上述路由為: ~~~ book_detail: path: /books/{id}.html defaults: { _controller: AppBundle:Book:detail } requirements: id: \d{5} ~~~ 通過一個簡單的正則表達式,我們約定`id`這個參數必須是5位數字,因此類似`1234`,`abcd8`這樣的參數將不會觸發這個路徑。訪問這樣的URI只會出現一個Apache自身的404頁面。 我個人認為,我會比較喜歡這種處理方式。這樣做的一個好處是減少了后臺控制器中的判斷。 ## 路由定義的陷阱 隨著我們應用的開發,路由的定義肯定會越來越多。我們有必要強調一些在路由定義時可能會犯的錯誤。 用YML定義的路由,遵循“最先匹配”的原則。某個URI只要符合某個特定的路徑模式就會觸發相應的動作。這么一來就可能會有問題。 假定在我們的路由文件中,有這樣兩個路由: ~~~ display_by_tag: path: /tag/{tag} add_tag: path: /tag/add requirements: _method: POST ~~~ 如果我們在一個表單中增加了一些tag,然后提交,我們的本意當然是要讓`add_tag`這個路由中指定的動作去執行為一本書增加tag的動作。但是,在這樣的路由配置情形下,首先被匹配的是`display_by_tag`這個路徑,因此我們試圖添加的tag不會真正地保存。 當然,要解決上面提到的問題也有很多方法。我們可以重新規劃路徑,調整路由定義的順序等。 一般而言,路由的設計需要考慮到兩點: 1. 簡單、直觀 2. 越是特殊的路由就要越早定義。 路由是SF中非常核心的一個部件。它可以由其它應用獨立引用。 對于路由的解說,本文只能給出最基本的講解。SF的[官方文檔中對于路由的說明](http://symfony.com/doc/current/book/routing.html)?才是最權威的指南。 本應用完整的[路由文件](https://github.com/taylorren/rsywx_tutorial/blob/master/src/AppBundle/Resources/config/routing.yml)已經上傳。 路由定義完畢后,我們需要開始模板的編寫。 > 1. 我們現在的應用因為只有樣本數據,所以是無法顯示出這樣的結果的。但是我們在后面會看到,即便如此,我們還是可以顯示一個示范的效果。[??](https://taylorr.gitbooks.io/building-a-web-site-with-symfony/content/05.06%20router.html#reffn_1 "Jump back to footnote [1] in the text.") > 2. 該頁面不是Apache自己的404頁面,而是我們定制的一個頁面。[??](https://taylorr.gitbooks.io/building-a-web-site-with-symfony/content/05.06%20router.html#reffn_2 "Jump back to footnote [2] in the text.")
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看