ホームページ バックエンド開発 PHPチュートリアル Symfony2のシステムルーティングの詳細説明

Symfony2のシステムルーティングの詳細説明

Jan 05, 2018 pm 05:46 PM
システム ルーティング

この記事では主に Symfony2 システムのルーティングを紹介し、Symfony のルーティング原理とルーティングの作成、構成、使用テクニックの詳細な分析を提供します。困っている友達が参考になれば幸いです。

本格的な Web アプリケーションには美しい URL が絶対に必要です。こうすることで、index.php?article_id=57 などの醜い URL が非表示になり、代わりに /read/intro-to-symfony などのより一般的な URL に置き換えられます。

柔軟性を持つことがより重要です。ページの URL を変更したい場合、たとえば /blog から /new に変更したい場合はどうすればよいでしょうか?

検索して更新する必要があるリンクはいくつありますか? Symfony のルーターを使用している場合、この変更は簡単です。

Symfony2 ルーターを使用すると、よりクリエイティブな URL を定義でき、アプリケーションのさまざまな領域をマッピングできます。

コントローラーにマッピングされた複雑なルートを作成し、テンプレートとコントローラー内で URL を生成できます

バンドル (または他の場所) からルート リソースをロードします

ルートをデバッグします

ルート アクティビティ

パスは URL パターンからのバインディングですコントローラーに。

/blog/my-post や /blog/all-about-symfony のような任意のパスを照合し、ブログ エンティティを検索してレンダリングできるコントローラーにそれらを送信するとします。

パスは単純です:

YAML形式:

# app/config/routing.yml
blog_show:
pattern: /blog/{slug}
defaults: {_controller: AcmeBlogBundle:Blog:show }
ログイン後にコピー

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="blog_show" pattern="/blog/{slug}">
<default key="_controller">AcmeBlogBundle:Blog:show</default>
</route>
</routes>
ログイン後にコピー

PHPコード形式:

// app/config/routing.php
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;
$collection = new RouteCollection();
$collection->add(&#39;blog_show&#39;, new Route(&#39;/blog/{slug}&#39;, array(
     &#39;_controller&#39; => &#39;AcmeBlogBundle:Blog:show&#39;,
)));
ログイン後にコピー

blog_showパスは/blog/*のようなURLパターンを定義します。ここでのワイルドカードはslugという名前です。 URL/blog/my-blog-post の場合、slug 変数は値 my-blog-post を取得します。
_controller パラメーターは、URL がこのパスに一致した場合にどのコントローラーが実行されるかを Symfogy に指示する特定のキーです。
_controller文字列を論理名といいます。その値は、特定のパターンに従って特定の PHP クラスとメソッドを指定します。

// 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(&#39;AcmeBlogBundle:Blog:show.html.twig&#39;, array(
      &#39;blog&#39; => $blog,
    ));
  }
}
ログイン後にコピー

これで、/blog/my-post に再度アクセスすると、showAction コントローラーが実行され、$slug 変数の値が my-post になります

Symfogy2 のルーター ターゲット: 要求された URL をコントローラーにマッピングします。

ルーティング: 内部の秘密

リクエストがアプリケーションに送信されるとき、そのリクエストにはクライアントが取得したいリソースのアドレスが含まれています。このアドレスは URL または URI と呼ばれます。 /contact、/blog/read-me またはその他のスタイルの場合があります。

GET /blog/my-blog-post

Symfony2 ルーティング システムの目標は、これらの URL を解析し、リクエストに応答するためにどのコントローラーを実行するかを決定することです。

ルーティングプロセス全体は次のように分割できます:

1. リクエストは Symfony2 のフロントエンドコントローラー (app.php) によって処理されます。
2.Symfony2 コア (カーネル) はルーターにリクエストを確認するように要求します。
3. ルーターは、受信した URL を特定のパスと照合し、実行する必要があるコントローラーなどの関連情報を返します。
4.Symfony2 コアはコントローラーを実行し、最終的に Response オブジェクトを返します。

ルーター層は受信したURLを特定のコントローラーに変換して実行するツールです。

ルートの作成

Symfony は、単一のルーティング設定ファイルからアプリケーションのすべてのルートをロードします。通常、このファイルは app/config/routing.yml です。 XML や PHP ファイルなどのファイルを含めるように構成できます。

YAML 形式:

# app/config/config.yml
framework:
  # ...
  router:    { resource: "%kernel.root_dir%/config/routing.yml" }
ログイン後にコピー

XML 形式:

<!-- app/config/config.xml -->
<framework:config ...>
  <!-- ... -->
  <framework:router resource="%kernel.root_dir%/config/routing.xml" />
</framework:config>
ログイン後にコピー

PHP コード形式:

// app/config/config.php
$container->loadFromExtension(&#39;framework&#39;, array(
  // ...
  &#39;router&#39;    => array(&#39;resource&#39; => &#39;%kernel.root_dir%/config/routing.php&#39;),
));
ログイン後にコピー

基本的なルーティング設定

ルートの定義は非常に簡単で、通常、アプリケーションには多くのルートがあります。基本ルートは、パターン部分とデフォルト配列部分の 2 つの部分で構成されます。
例:

YAML 形式:

_welcome:
  pattern:  /
  defaults: { _controller: AcmeDemoBundle:Main:homepage }
ログイン後にコピー

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="_welcome" pattern="/">
    <default key="_controller">AcmeDemoBundle:Main:homepage</default>
  </route>
</routes>
ログイン後にコピー

PHP コード形式:

use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;
$collection = new RouteCollection();
$collection->add(&#39;_welcome&#39;, new Route(&#39;/&#39;, array(
  &#39;_controller&#39; => &#39;AcmeDemoBundle:Main:homepage&#39;,
)));
return $collection;
ログイン後にコピー

このルートはホームページ (/) に一致し、AcmeDemoBundle:Main:homepage コントローラーにマップされます。 _controller 文字列は、Symfony2 によって対応する PHP 関数に変換され、実行されます。

プレースホルダーを使用したルーティング

もちろん、ルーティング システムは、より興味深いルートをサポートしています。多くのルートには、1 つ以上の名前付きワイルドカード プレースホルダーが含まれています。

YAML 形式:

blog_show:
  pattern:  /blog/{slug}
  defaults: { _controller: AcmeBlogBundle:Blog:show }
ログイン後にコピー

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 コード形式:

use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;
$collection = new RouteCollection();
$collection->add(&#39;blog_show&#39;, new Route(&#39;/blog/{slug}&#39;, array(
  &#39;_controller&#39; => &#39;AcmeBlogBundle:Blog:show&#39;,
)));
return $collection;
ログイン後にコピー

このパターンは、/blog/* に類似した任意の URL に一致します。プレースホルダー {slug} に一致する値がコントローラーで使用されます。つまり、URL が /blog/hello-world の場合、$slug 変数の値は hello-world となり、この値はコントローラーで使用可能になります。デフォルトではすべてのプレースホルダーが必須であるため、このパターンは /blog などとは一致しません。 もちろん、これらのプレースホルダーをデフォルト配列に割り当てることで、これを変更できます。

必須およびオプションのプレースホルダー

利用可能なすべてのブログのリストを表示する新しいルートを追加しましょう。

YAML 形式:

blog:
  pattern:  /blog
  defaults: { _controller: AcmeBlogBundle:Blog:index }
ログイン後にコピー

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" pattern="/blog">
    <default key="_controller">AcmeBlogBundle:Blog:index</default>
  </route>
</routes>
ログイン後にコピー

PHP コード形式:

use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;
$collection = new RouteCollection();
$collection->add(&#39;blog&#39;, new Route(&#39;/blog&#39;, array(
  &#39;_controller&#39; => &#39;AcmeBlogBundle:Blog:index&#39;,
)));
return $collection;
ログイン後にコピー

これまでのルートは、非常に単純なルーティング パターンでした。それらに含まれる非プレースホルダーは正確に一致します。

このルートでページングをサポートしたい場合、たとえば、/blog/2 にブログの 2 ページ目を表示させる場合は、新しい {page} プレースホルダーを前のルートに追加する必要があります。

YAML形式:

blog:
  pattern:  /blog/{page}
  defaults: { _controller: AcmeBlogBundle:Blog:index }
ログイン後にコピー

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" pattern="/blog/{page}">
    <default key="_controller">AcmeBlogBundle:Blog:index</default>
  </route>
</routes>
ログイン後にコピー

PHPコード形式:

use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;
$collection = new RouteCollection();
$collection->add(&#39;blog&#39;, new Route(&#39;/blog/{page}&#39;, array(
  &#39;_controller&#39; => &#39;AcmeBlogBundle:Blog:index&#39;,
)));
return $collection;
ログイン後にコピー

跟之前的{slug}占位符一样{page}占位符将会在你的controller内部可用,它的值可以用于表示要显示的blog值的页码。但是要清楚,因为占位符默认情况下都是必需的,该路由也将不再匹配之前的/blog URL,这时候你如果还像看第一页的话,就必须通过/blog/1 URL来访问了。要解决该问题,可以在该路由的defaults数组中指定{page}的默认值。

YAML格式:

blog:
  pattern:  /blog/{page}
  defaults: { _controller: AcmeBlogBundle:Blog:index, page: 1 }
ログイン後にコピー

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" pattern="/blog/{page}">
    <default key="_controller">AcmeBlogBundle:Blog:index</default>
    <default key="page">1</default>
  </route>
</routes>
ログイン後にコピー

PHP代码格式:

use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;
$collection = new RouteCollection();
$collection->add(&#39;blog&#39;, new Route(&#39;/blog/{page}&#39;, array(
  &#39;_controller&#39; => &#39;AcmeBlogBundle:Blog:index&#39;,
  &#39;page&#39; => 1,
)));
return $collection;
ログイン後にコピー

通过添加page到defaults键, {page}占位符就不再是必需的。这时候 /blog将会被匹配并且page参数被设置为1,URL /blog/2 也会被匹配。

添加要求约束

看看下面这些路由:

YAML格式:

blog:
  pattern:  /blog/{page}
  defaults: { _controller: AcmeBlogBundle:Blog:index, page: 1 }
blog_show:
  pattern:  /blog/{slug}
  defaults: { _controller: AcmeBlogBundle:Blog:show }
ログイン後にコピー

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" 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代码格式:

use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;
$collection = new RouteCollection();
$collection->add(&#39;blog&#39;, new Route(&#39;/blog/{page}&#39;, array(
  &#39;_controller&#39; => &#39;AcmeBlogBundle:Blog:index&#39;,
  &#39;page&#39; => 1,
)));
$collection->add(&#39;blog_show&#39;, new Route(&#39;/blog/{show}&#39;, array(
  &#39;_controller&#39; => &#39;AcmeBlogBundle:Blog:show&#39;,
)));
return $collection;
ログイン後にコピー

你发现问题了吗?注意这两个路由都能匹配像/blog/* 类型的URL。Symfony只会选择第一个与之匹配的路由。

换句话说,blog_show将永远不会被像/blog/* 类型的URL匹配。而像 /blog/my-blog-post这样的URL也会被blog路由匹配,并且page变量会获得my-blog-post这样的值。

这肯定不可以,那么怎么办呢?答案是给路由添加约束要求requirements。

在blog路由中占位符{page}理想状态下只匹配整数值。幸运的是正则表达可以很容易的满足这一要求。

YAML格式:

blog:
  pattern:  /blog/{page}
  defaults: { _controller: AcmeBlogBundle:Blog:index, page: 1 }
  requirements:
    page: \d+
ログイン後にコピー

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" pattern="/blog/{page}">
    <default key="_controller">AcmeBlogBundle:Blog:index</default>
    <default key="page">1</default>
    <requirement key="page">\d+</requirement>
  </route>
</routes>
ログイン後にコピー

PHP代码格式:

use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;
$collection = new RouteCollection();
$collection->add(&#39;blog&#39;, new Route(&#39;/blog/{page}&#39;, array(
  &#39;_controller&#39; => &#39;AcmeBlogBundle:Blog:index&#39;,
  &#39;page&#39; => 1,
), array(
  &#39;page&#39; => &#39;\d+&#39;,
)));
return $collection;
ログイン後にコピー

这里 \d+ 约束是一个正则表达式,它指定了{page}只接受整数。这样像/blog/my-blog-post就不再被匹配了。这时候,它才会被blog_show路由匹配。因为参数的约束都是正则表达式,所以其复杂程度和灵活性都有你来决定了。
假设home页使用两种语言则可以这样配置路由:

YAML格式:

homepage:
  pattern:  /{culture}
  defaults: { _controller: AcmeDemoBundle:Main:homepage, culture: en }
  requirements:
    culture: en|fr
ログイン後にコピー

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="homepage" pattern="/{culture}">
    <default key="_controller">AcmeDemoBundle:Main:homepage</default>
    <default key="culture">en</default>
    <requirement key="culture">en|fr</requirement>
  </route>
</routes>
ログイン後にコピー

PHP代码格式:

use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;
$collection = new RouteCollection();
$collection->add(&#39;homepage&#39;, new Route(&#39;/{culture}&#39;, array(
  &#39;_controller&#39; => &#39;AcmeDemoBundle:Main:homepage&#39;,
  &#39;culture&#39; => &#39;en&#39;,
), array(
  &#39;culture&#39; => &#39;en|fr&#39;,
)));
return $collection;
ログイン後にコピー

添加HTTP 方法约束

除了URL,你还可以匹配请求的方法(GET,HEAD,POST,PUT,DELETE等)。假设你有一个联系表单有两个controller,一个用于显示表单(使用GET请求)一个用于处理提交的表单(POST请求)。它的配置如下:

YAML格式:

contact:
  pattern: /contact
  defaults: { _controller: AcmeDemoBundle:Main:contact }
  requirements:
    _method: GET
contact_process:
  pattern: /contact
  defaults: { _controller: AcmeDemoBundle:Main:contactProcess }
  requirements:
    _method: POST
ログイン後にコピー

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="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代码格式:

use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;
$collection = new RouteCollection();
$collection->add(&#39;contact&#39;, new Route(&#39;/contact&#39;, array(
  &#39;_controller&#39; => &#39;AcmeDemoBundle:Main:contact&#39;,
), array(
  &#39;_method&#39; => &#39;GET&#39;,
)));
$collection->add(&#39;contact_process&#39;, new Route(&#39;/contact&#39;, array(
  &#39;_controller&#39; => &#39;AcmeDemoBundle:Main:contactProcess&#39;,
), array(
  &#39;_method&#39; => &#39;POST&#39;,
)));
return $collection;
ログイン後にコピー

尽管这两个路由拥有同一个URL模式定义(/contact),但是第一个路由只会匹配GET请求,而第二个只会匹配POST请求。这就意味着你可以通过同一个URL来显示表单并提交表单,而用不同的controller对他们进行处理。如果没有指定_method约束,那么该路由会匹配所有请求方法。跟其它约束一样,_method约束也接受正则表达式,如果只想匹配GET或者POST那么你可以用GET|POST

高级路由例子:

Symfony2中具备一切让你创建任何形式路由的条件。

YAML格式:

article_show:
 pattern: /articles/{culture}/{year}/{title}.{_format}
 defaults: { _controller: AcmeDemoBundle:Article:show, _format: html }
 requirements:
   culture: en|fr
   _format: html|rss
   year:   \d+
ログイン後にコピー

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="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代码格式:

use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;
$collection = new RouteCollection();
$collection->add(&#39;homepage&#39;, new Route(&#39;/articles/{culture}/{year}/{title}.{_format}&#39;, array(
  &#39;_controller&#39; => &#39;AcmeDemoBundle:Article:show&#39;,
  &#39;_format&#39; => &#39;html&#39;,
), array(
  &#39;culture&#39; => &#39;en|fr&#39;,
  &#39;_format&#39; => &#39;html|rss&#39;,
  &#39;year&#39; => &#39;\d+&#39;,
)));
return $collection;
ログイン後にコピー

上面的路由,在匹配时只会匹配{culture}部分值为en或者fr并且{year}的值为数字的URL。该路由还告诉我们,可以用在占位符之间使用区间代替斜线。

它能够匹配如下URL:

/articles/en/2010/my-post
/articles/fr/2010/my-post.rss

这其中有个特殊的路由参数 _format,在使用该参数时,其值变为请求格式。这种请求格式相当于Respose对象的Content-Type,比如json请求格式会翻译成一个Content-Type为application/json.该参数可以用于在controller中为每个_format渲染一个不同的模板。它是一个很强的方式来渲染同一个内容到不同的格式。

特殊的路由参数:

正如你所看到的,每一个路由参数或者默认值最终都是作为一个controller方法输入参数被使用。另外,有三个参数比较特别,它们每一个都在你的应用程序中增加一个唯一功能。

_controller: 这个参数决定了当路由匹配时,哪个controller被执行。
_format: 用于设置请求格式。
_locale: 用于在session上设置本地化。

Controller的命名模式:

每一个路由必须有一个_controller参数,它决定了当路由匹配时哪个controller应该被执行。该参数使用单一的字符串模式,被称为logical controller name。

通过它Symfony可以映射到一个特定的PHP方法和类。该模式有三部分,每一部分用冒号分割开:

bundle:controller:action
ログイン後にコピー

比如_controller 的值为 AcmeBlogBundle:Blog:show 意思是AcmeBlogBundle bundle中BlogController类里面的showAction方法。

// src/Acme/BlogBundle/Controller/BlogController.php
namespace Acme\BlogBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class BlogController extends Controller
{
  public function showAction($slug)
  {
    // ...
  }
}
ログイン後にコピー

Symfony会自动把它们的添加相应的后缀,Blog=>BlogController, show => showAction。

你也可以使用它的完全限定名和方法来给_controller赋值,Acme\BlogBundle\Controller\BlogController::showAction 但一般为了简洁灵活而是用逻辑名称。另外除了上面两种形式外,Symfony还支持第三种方式只有一个冒号分割符,如service_name:indexAction来为_controller赋一个作为服务使用的controller。

路由参数和控制器参数

路由参数非常重要,因为每一个路由参数都会转变成一个控制器参数被在方法中使用。

public function showAction($slug)
{
 // ...
}
ログイン後にコピー

事实上,全部的defaults集合和表单的参数值合并到一个单独的数组中。这个数组中的每个键都会成为controller方法的参数。换句话说,你的controller方法的每一个参数,Symfony都会从路由参数中查找并把找到的值赋给给参数。上面例子中的变量 $culture, $year,$title,$_format,$_controller 都会作为showAction()方法的参数。因为占位符和defaults集合被合并到一起,即使$_controller变量也是一样。你也可以使用一个特殊的变量$_route 来指定路由的名称。

包括外部路由资源

所有的路由资源的都是通过一个单一的配置文件导入的。通常是app/config/routing.yml。当然你可能想从别处导入路由资源,比如你定义的bundle中的路由资源,你可以这样导入:

YAML格式:

# app/config/routing.yml
acme_hello:
  resource: "@AcmeHelloBundle/Resources/config/routing.yml"
ログイン後にコピー

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">
  <import resource="@AcmeHelloBundle/Resources/config/routing.xml" />
</routes>
ログイン後にコピー

PHP代码格式:

// app/config/routing.php
use Symfony\Component\Routing\RouteCollection;
$collection = new RouteCollection();
$collection->addCollection($loader->import("@AcmeHelloBundle/Resources/config/routing.php"));
return $collection;
ログイン後にコピー

在使用YAML导入资源时,键(比如acme_hello)是没有意义的,只是用来保证该资源唯一不被其它行覆盖。使用resources key加载给定的路由资源。在这个示例中资源是一个全路径文件,@AcmeHelloBundle是简写语法,它会被指向bundle路径。被导入的文件内容如下:

YAML格式:

# src/Acme/HelloBundle/Resources/config/routing.yml
acme_hello:
   pattern: /hello/{name}
   defaults: { _controller: AcmeHelloBundle:Hello:index }
ログイン後にコピー

XML格式:

<!-- 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代码格式:

// src/Acme/HelloBundle/Resources/config/routing.php
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;
$collection = new RouteCollection();
$collection->add(&#39;acme_hello&#39;, new Route(&#39;/hello/{name}&#39;, array(
  &#39;_controller&#39; => &#39;AcmeHelloBundle:Hello:index&#39;,
)));
return $collection;
ログイン後にコピー

这个文件中的路由会被解析并跟主要的路由文件内容一起被加载。

给导入的路由资源添加前缀

你可以为导入的路由资源选择一个前缀,比如说假设你想acme_hello路由有一个这样的 匹配模式:/admin/hello/{name} 而不是直接的 /hello/{name}

那么你在导入它的时候可以为其指定prefix。

YAML格式:

# app/config/routing.yml
acme_hello:
  resource: "@AcmeHelloBundle/Resources/config/routing.yml"
  prefix:  /admin
ログイン後にコピー

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">
  <import resource="@AcmeHelloBundle/Resources/config/routing.xml" prefix="/admin" />
</routes>
ログイン後にコピー

PHP代码格式:

// app/config/routing.php
use Symfony\Component\Routing\RouteCollection;
$collection = new RouteCollection();
$collection->addCollection($loader->import("@AcmeHelloBundle/Resources/config/routing.php"), &#39;/admin&#39;);
return $collection;
ログイン後にコピー

当该外部路由资源加载的时候字符串 /admin 将被插入到匹配模式的前面。

可视化并调试路由

当你添加和个性化路由时,能够看到它并能获取一些细节信息将是非常有用的。一个好的查看你应用程序的路由的方法是通过router:debug 命令行工具。

在你项目目录下执行如下命令:

$ php app/console router:debug
ログイン後にコピー

将会输出你应用程序的所有路由。你也可以在该命令后面添加某个路由的名字来获取单个路由信息

$ php app/console router:debug article_show
ログイン後にコピー

生成URL

一个路由系统应该也能用来生成URL。事实上,路由系统是一个双向的系统,映射URL到controller+parameters 和 回对应到 一个URL。可以使用match()和generate()方法来操作。比如:

$params = $router->match(&#39;/blog/my-blog-post&#39;);
// array(&#39;slug&#39; => &#39;my-blog-post&#39;, &#39;_controller&#39; => &#39;AcmeBlogBundle:Blog:show&#39;)
$uri = $router->generate(&#39;blog_show&#39;, array(&#39;slug&#39; => &#39;my-blog-post&#39;));
// /blog/my-blog-post
ログイン後にコピー

要生成一个URL,你需要指定路由的名称(比如 blog_show)和任意的通配符(比如:slug=my-blog-post)作为参数。通过这些信息,可以生成任意的URL。

class MainController extends Controller
{
  public function showAction($slug)
  {
   // ...
   $url = $this->get(&#39;router&#39;)->generate(&#39;blog_show&#39;, array(&#39;slug&#39; => &#39;my-blog-post&#39;));
  }
}
ログイン後にコピー

那么如何从模板内部来生成URL呢?如果你的应用程序前端使用了AJAX请求,你也许想能够基于你的路由配置在javascript中生成URL,通过使用

FOSJsRoutingBundle(https://github.com/FriendsOfSymfony/FOSJsRoutingBundle) 你可以做到:

var url = Routing.generate(&#39;blog_show&#39;, { "slug": &#39;my-blog-post&#39;});
ログイン後にコピー

生成绝对路径的URL

默认的情况下,路由器生成相对路径的URL(比如 /blog).要生成一个绝对路径的URL,只需要传入一个true到generate方法作为第三个参数值即可。

$router->generate(&#39;blog_show&#39;, array(&#39;slug&#39; => &#39;my-blog-post&#39;), true);
// http://www.example.com/blog/my-blog-post
ログイン後にコピー

当生成一个绝对路径URL时主机是当前请求对象的主机,这个是基于PHP提供的服务器信息自动决定的。当你需要为运行子命令行的脚本生成一个绝对URL时,你需要在Request对象上手动设置期望的主机头。

$request->headers->set(&#39;HOST&#39;, &#39;www.example.com&#39;);
ログイン後にコピー

生成带有查询字符串的URL

generate()带有一个数组通配符值来生成URI。 但是如果你传入额外的值,它将被添加到URI作为查询字符串:

$router->generate(&#39;blog&#39;, array(&#39;page&#39; => 2, &#39;category&#39; => &#39;Symfony&#39;));
// /blog/2?category=Symfony
ログイン後にコピー

从模板中生成URL

最常用到生成URL的地方是从模板中链接两个页面时,这来需要使用一个模板帮助函数:

Twig格式:

<a href="{{ path(&#39;blog_show&#39;, { &#39;slug&#39;: &#39;my-blog-post&#39; }) }}">
 Read this blog post.
</a>
ログイン後にコピー

PHP格式:

<a href="<?php echo $view[&#39;router&#39;]->generate(&#39;blog_show&#39;, array(&#39;slug&#39; => &#39;my-blog-post&#39;)) ?>">
  Read this blog post.
</a>
ログイン後にコピー

也可以生成绝对路径:

Twig格式:

<a href="{{ url(&#39;blog_show&#39;, { &#39;slug&#39;: &#39;my-blog-post&#39; }) }}">
 Read this blog post.
</a>
ログイン後にコピー

PHP格式:

<a href="<?php echo $view[&#39;router&#39;]->generate(&#39;blog_show&#39;, array(&#39;slug&#39; => &#39;my-blog-post&#39;), true) ?>">
  Read this blog post.
</a>
ログイン後にコピー

强制路由使用HTTPS或者HTTP

有时候为了安全起见,你需要你的站点必须使用HTTPS协议访问。这时候路由组件可以通过_scheme 约束来强迫URI方案。比如:

YAML格式:

secure:
  pattern: /secure
  defaults: { _controller: AcmeDemoBundle:Main:secure }
  requirements:
    _scheme: https
ログイン後にコピー

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="secure" pattern="/secure">
    <default key="_controller">AcmeDemoBundle:Main:secure</default>
    <requirement key="_scheme">https</requirement>
  </route>
</routes>
ログイン後にコピー

PHP代码格式:

use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;
$collection = new RouteCollection();
$collection->add(&#39;secure&#39;, new Route(&#39;/secure&#39;, array(
  &#39;_controller&#39; => &#39;AcmeDemoBundle:Main:secure&#39;,
), array(
  &#39;_scheme&#39; => &#39;https&#39;,
)));
return $collection;
ログイン後にコピー

上面的路由定义就是强迫secure路由使用HTTPS协议访问。

反之,当生成secure 的URL的时候,路由系统会根据当前的访问协议方案生成相应的访问协议。比如当前是HTTP,则会自动生成HTTPS访问;如果是HTTPS访问,那么就也会相应的生成HTTPS访问。

# 如果方案是 HTTPS
{{ path(&#39;secure&#39;) }}
# 生成 /secure
# 如果方案是 HTTP
{{ path(&#39;secure&#39;) }}
# 生成 https://example.com/secure
ログイン後にコピー

当然你也可以通过设置_scheme为HTTP,来强制使用HTTP访问协议。除了上面说的强迫使用HTTPS协议访问的设置方法外,还有一种用于站点区域设置

使用requires_channel 比如你想让你站点中/admin 下面的所有路由都必须使用HTTPS协议访问,或者你的安全路由定义在第三方bundle时使用。

总结:

路由系统是一个为将接收的请求URL映射到被调用来处理该请求的controller函数的系统。它既能够让你生成漂亮的URL同时又能保持你的应用程序功能跟这些URL解耦。路由系统是双向机制的,也就是说它们也可以用来生成URL。

相关推荐:

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

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

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

以上がSymfony2のシステムルーティングの詳細説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

CUDA の汎用行列乗算: 入門から習熟まで! CUDA の汎用行列乗算: 入門から習熟まで! Mar 25, 2024 pm 12:30 PM

General Matrix Multiplication (GEMM) は、多くのアプリケーションやアルゴリズムの重要な部分であり、コンピューター ハードウェアのパフォーマンスを評価するための重要な指標の 1 つでもあります。 GEMM の実装に関する徹底的な調査と最適化は、ハイ パフォーマンス コンピューティングとソフトウェア システムとハードウェア システムの関係をより深く理解するのに役立ちます。コンピューター サイエンスでは、GEMM を効果的に最適化すると、計算速度が向上し、リソースが節約されます。これは、コンピューター システムの全体的なパフォーマンスを向上させるために非常に重要です。 GEMM の動作原理と最適化方法を深く理解することは、最新のコンピューティング ハードウェアの可能性をより有効に活用し、さまざまな複雑なコンピューティング タスクに対してより効率的なソリューションを提供するのに役立ちます。 GEMMのパフォーマンスを最適化することで

ファーウェイのQiankun ADS3.0インテリジェント運転システムは8月に発売され、初めてXiangjie S9に搭載される ファーウェイのQiankun ADS3.0インテリジェント運転システムは8月に発売され、初めてXiangjie S9に搭載される Jul 30, 2024 pm 02:17 PM

7月29日、AITO Wenjieの40万台目の新車のロールオフ式典に、ファーウェイの常務取締役、ターミナルBG会長、スマートカーソリューションBU会長のYu Chengdong氏が出席し、スピーチを行い、Wenjieシリーズモデルの発売を発表した。 8月にHuawei Qiankun ADS 3.0バージョンが発売され、8月から9月にかけて順次アップグレードが行われる予定です。 8月6日に発売されるXiangjie S9には、ファーウェイのADS3.0インテリジェント運転システムが初搭載される。 LiDARの支援により、Huawei Qiankun ADS3.0バージョンはインテリジェント運転機能を大幅に向上させ、エンドツーエンドの統合機能を備え、GOD(一般障害物識別)/PDP(予測)の新しいエンドツーエンドアーキテクチャを採用します。意思決定と制御)、駐車スペースから駐車スペースまでのスマート運転のNCA機能の提供、CAS3.0のアップグレード

Apple 16 システムのどのバージョンが最適ですか? Apple 16 システムのどのバージョンが最適ですか? Mar 08, 2024 pm 05:16 PM

Apple 16 システムの最適なバージョンは iOS16.1.4 です。iOS16 システムの最適なバージョンは人によって異なります。日常の使用体験における追加と改善も多くのユーザーから賞賛されています。 Apple 16 システムの最適なバージョンはどれですか? 回答: iOS16.1.4 iOS 16 システムの最適なバージョンは人によって異なる場合があります。公開情報によると、2022 年にリリースされた iOS16 は非常に安定していてパフォーマンスの高いバージョンであると考えられており、ユーザーはその全体的なエクスペリエンスに非常に満足しています。また、iOS16では新機能の追加や日常の使用感の向上も多くのユーザーからご好評をいただいております。特に最新のバッテリー寿命、信号性能、加熱制御に関して、ユーザーからのフィードバックは比較的好評です。ただし、iPhone14を考慮すると、

常に新しい! Huawei Mate60シリーズがHarmonyOS 4.2にアップグレード:AIクラウドの強化、Xiaoyi方言はとても使いやすい 常に新しい! Huawei Mate60シリーズがHarmonyOS 4.2にアップグレード:AIクラウドの強化、Xiaoyi方言はとても使いやすい Jun 02, 2024 pm 02:58 PM

4月11日、ファーウェイはHarmonyOS 4.2 100台のアップグレード計画を初めて正式に発表し、今回は携帯電話、タブレット、時計、ヘッドフォン、スマートスクリーンなどのデバイスを含む180台以上のデバイスがアップグレードに参加する予定だ。先月、HarmonyOS4.2 100台アップグレード計画の着実な進捗に伴い、Huawei Pocket2、Huawei MateX5シリーズ、nova12シリーズ、Huawei Puraシリーズなどの多くの人気モデルもアップグレードと適応を開始しました。 HarmonyOS によってもたらされる共通の、そして多くの場合新しい体験を楽しむことができる Huawei モデルのユーザーが増えることになります。ユーザーのフィードバックから判断すると、HarmonyOS4.2にアップグレードした後、Huawei Mate60シリーズモデルのエクスペリエンスがあらゆる面で向上しました。特にファーウェイM

コンピュータのオペレーティング システムとは何ですか? コンピュータのオペレーティング システムとは何ですか? Jan 12, 2024 pm 03:12 PM

コンピュータ オペレーティング システムは、コンピュータ ハードウェアとソフトウェア プログラムを管理するために使用されるシステムです。また、すべてのソフトウェア システムに基づいて開発されたオペレーティング システム プログラムでもあります。オペレーティング システムが異なれば、ユーザーも異なります。では、コンピュータ システムとは何でしょうか?以下では、編集者がコンピューターのオペレーティング システムとは何かについて説明します。いわゆるオペレーティング システムはコンピュータのハードウェアとソフトウェア プログラムを管理するもので、すべてのソフトウェアはオペレーティング システム プログラムに基づいて開発されます。実際、OSには産業用、商業用、個人用など多くの種類があり、幅広い用途に対応しています。以下では、編集者がコンピューターのオペレーティングシステムとは何かについて説明します。 Windows システムとはどのようなコンピュータのオペレーティング システムですか? Windows システムは、米国 Microsoft Corporation によって開発されたオペレーティング システムです。ほとんどよりも

Oracleデータベースのシステム日付を変更する方法の詳細な説明 Oracleデータベースのシステム日付を変更する方法の詳細な説明 Mar 09, 2024 am 10:21 AM

Oracle データベースでのシステム日付の変更方法の詳細説明 Oracle データベースでのシステム日付の変更方法は、主に NLS_DATE_FORMAT パラメータの変更と SYSDATE 関数の使用です。この記事では、読者が Oracle データベースのシステム日付を変更する操作をよりよく理解し、習得できるように、これら 2 つの方法とその具体的なコード例を詳しく紹介します。 1. NLS_DATE_FORMAT パラメータメソッドの変更 NLS_DATE_FORMAT は Oracle データです

Linux と Windows システムにおける cmd コマンドの相違点と類似点 Linux と Windows システムにおける cmd コマンドの相違点と類似点 Mar 15, 2024 am 08:12 AM

Linux と Windows は 2 つの一般的なオペレーティング システムで、それぞれオープン ソースの Linux システムと商用 Windows システムを表します。どちらのオペレーティング システムにも、ユーザーがオペレーティング システムと対話するためのコマンド ライン インターフェイスがあります。 Linux システムでは、ユーザーはシェル コマンド ラインを使用しますが、Windows システムでは、cmd コマンド ラインを使用します。 Linux システムのシェル コマンド ラインは、ほぼすべてのシステム管理タスクを完了できる非常に強力なツールです。

Java Apache Camel: 柔軟で効率的なサービス指向アーキテクチャの構築 Java Apache Camel: 柔軟で効率的なサービス指向アーキテクチャの構築 Feb 19, 2024 pm 04:12 PM

Apache Camel は、異種のアプリケーション、サービス、データ ソースを簡単に統合して、複雑なビジネス プロセスを自動化できる Enterprise Service Bus (ESB) ベースの統合フレームワークです。 ApacheCamel はルートベースの構成を使用して、統合プロセスを簡単に定義および管理します。 ApacheCamel の主な機能は次のとおりです。 柔軟性: ApacheCamel は、さまざまなアプリケーション、サービス、データ ソースと簡単に統合できます。 HTTP、JMS、SOAP、FTP などの複数のプロトコルをサポートします。効率: ApacheCamel は非常に効率的で、大量のメッセージを処理できます。非同期メッセージング メカニズムを使用しているため、パフォーマンスが向上します。拡張可能

See all articles