天天看點

使用Symfony路由元件在PHP應用程式中設定路由

今天,我們将介紹Symfony路由元件,該元件可讓您在PHP應用程式中設定路由。

什麼是Symfony路由元件?

Symfony路由元件是一種非常流行的路由元件,可以通過多種架構進行修改,如果您希望在PHP應用程式中設定路由,則可以提供很大的靈活性。

如果您已經建構了一個自定義PHP應用程式,并且正在尋找功能豐富的路由庫,那麼Symfony Routing Component絕對值得一看。 它還允許您以YAML格式為應用程式定義路由。

從安裝和配置開始,我們将通過實際示例示範該元件用于路由配置的各種選項。 在本文中,您将學習:

  • 安裝和配置
  • 如何設定基本路線
  • 如何從YAML檔案加載路由
  • 如何使用多合一路由器

安裝與配置

在本節中,我們将安裝在PHP應用程式中設定路由所需的庫。 我假設您已經在系統中安裝了Composer,因為我們需要它來安裝Packagist上可用的必要庫。

安裝Composer後,請繼續并使用以下指令安裝核心“路由”元件。

$composer require symfony/routing
           

盡管路由元件本身足以在您的應用程式中提供全面的路由功能,但我們仍将繼續安裝其他一些元件,以使我們的生活更輕松并豐富現有的核心路由功能。

首先,我們将繼續安裝HttpFoundation元件,該元件為PHP全局變量和與響應相關的函數提供了面向對象的包裝。 它可以確定您不需要直接通路

$_GET

$_POST

之類的全局變量。

$composer require symfony/http-foundation
           

接下來,如果要在YAML檔案中定義應用程式路由而不是在PHP代碼中定義,則可以使用YAML元件,因為它可以幫助您将YAML字元串轉換為PHP數組,反之亦然。

$composer require symfony/yaml
           

最後,我們将安裝Config元件,該元件提供了幾個實用程式類來初始化和處理在不同類型的檔案(如YAML,INI,XML等)中定義的配置值。在本例中,我們将使用它來加載路由從YAML檔案中。

$composer require symfony/config
           

這就是安裝部分,但是您應該如何使用它呢? 實際上,隻需要在應用程式中包含由Composer建立的autoload.php檔案即可,如以下代碼片段所示。

<?php
require_once './vendor/autoload.php';

// application code
?>
           

設定基本路線

在上一節中,我們完成了必要的路由元件的安裝。 現在,您可以立即在PHP應用程式中設定路由。

讓我們繼續建立具有以下内容的basic_routes.php檔案。

<?php
require_once './vendor/autoload.php';

use Symfony\Component\Routing\Matcher\UrlMatcher;
use Symfony\Component\Routing\RequestContext;
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Generator\UrlGenerator;
use Symfony\Component\Routing\Exception\ResourceNotFoundException;

try
{
    // Init basic route
    $foo_route = new Route(
      '/foo',
      array('controller' => 'FooController')
    );

    // Init route with dynamic placeholders
    $foo_placeholder_route = new Route(
      '/foo/{id}',
      array('controller' => 'FooController', 'method'=>'load'),
      array('id' => '[0-9]+')
    );

    // Add Route object(s) to RouteCollection object
    $routes = new RouteCollection();
    $routes->add('foo_route', $foo_route);
    $routes->add('foo_placeholder_route', $foo_placeholder_route);

    // Init RequestContext object
    $context = new RequestContext();
    $context->fromRequest(Request::createFromGlobals());

    // Init UrlMatcher object
    $matcher = new UrlMatcher($routes, $context);

    // Find the current route
    $parameters = $matcher->match($context->getPathInfo());

    // How to generate a SEO URL
    $generator = new UrlGenerator($routes, $context);
    $url = $generator->generate('foo_placeholder_route', array(
      'id' => 123,
    ));

    echo '<pre>';
    print_r($parameters);

    echo 'Generated URL: ' . $url;
    exit;
}
catch (ResourceNotFoundException $e)
{
  echo $e->getMessage();
}
           

使用Symfony路由元件設定路由通常需要完成以下一系列步驟。

  • 為每個應用程式路由初始化

    Route

    對象。
  • 将所有

    Route

    對象添加到

    RouteCollection

    對象。
  • 初始化儲存目前請求上下文資訊的

    RequestContext

    對象。
  • 初始化

    UrlMatcher

    通過使對象

    RouteCollection

    對象和

    RequestContext

    對象。

初始化不同路線的路線對象

讓我們繼續定義一個非常基本的

foo

路由。

$foo_route = new Route(
  '/foo',
  array('controller' => 'FooController')
);
           

Route

構造函數的第一個參數是URI路徑,第二個參數是要比對此特定路由時要傳回的自定義屬性的數組。 通常,它将是請求此路由時要調用的控制器和方法的組合。

接下來,讓我們看一下參數化的路由。

$foo_placeholder_route = new Route(
  '/foo/{id}',
  array('controller' => 'FooController', 'method'=>'load'),
  array('id' => '[0-9]+')
);
           

上面的路由可以比對

foo/1

foo/123

類的URI。 請注意,我們僅将

{id}

參數限制為數字值,是以,由于

{id}

參數是作為字元串提供的,是以它與

foo/bar

類的URI不比對。

将所有路由對象添加到RouteCollection對象

下一步是将我們在上一節中初始化的路由對象添加到

RouteCollection

對象。

$routes = new RouteCollection();
$routes->add('foo_route', $foo_route);
$routes->add('foo_placeholder_route', $foo_placeholder_route);
           

如您所見,這非常簡單,因為您隻需要使用

RouteCollection

對象的

add

方法來添加路由對象。

add

方法的第一個參數是路由的名稱,第二個參數是路由對象本身。

初始化

RequestContext

對象

接下來,我們需要初始化

RequestContext

對象,該對象儲存目前的請求上下文資訊。 初始化

UrlMatcher

對象時,将需要該對象,

UrlMatcher

我們将進行介紹。

$context = new RequestContext();
$context->fromRequest(Request::createFromGlobals());
           

初始化

UrlMatcher

對象

最後,我們需要初始化

UrlMatcher

對象以及路由和上下文資訊。

// Init UrlMatcher object
$matcher = new UrlMatcher($routes, $context);
           

現在,我們擁有了所有可以與之匹敵的路線。

如何比對路線

這是

UrlMatcher

對象的

match

方法,它允許您将任何路由與一組預定義的路由進行比對。

match

方法将URI作為其第一個參數,并嘗試将其與預定義的路由進行比對。 如果找到該路由,它将傳回與該路由關聯的自定義屬性。 另一方面,如果沒有與目前URI關聯的路由,它将引發

ResourceNotFoundException

異常。

$parameters = $matcher->match($context->getPathInfo());
           

在我們的例子中,我們通過從

$context

對象擷取目前URI來提供它。 是以,如果您通路http://your-domain/basic_routes.php/foo URL,則

$context->getPathInfo()

context-

$context->getPathInfo()

傳回

foo

,并且我們已經為

foo

URI定義了一條路由,是以應該傳回以下内容。

Array
(
    [controller] => FooController
    [_route] => foo_route
)
           

現在,讓我們繼續通過通路http://your-domain/basic_routes.php/foo/123 URL來測試參數化路由。

Array
(
    [controller] => FooController
    [method] => load
    [id] => 123
    [_route] => foo_placeholder_route
)
           

如果您可以看到

id

參數與适當的值

123

綁定,則此方法有效。

接下來,讓我們嘗試通路不存在的路由,例如http://your-domain/basic_routes.php/unknown-route ,您應該看到以下消息。

No routes found for "/unknown-route".
           

這樣便可以使用

match

方法查找路線。

除此之外,您還可以使用“

Routing

元件在應用程式中生成連結。 提供

RouteCollection

RequestContext

對象,在

UrlGenerator

允許你建立特定路由連結。

$generator = new UrlGenerator($routes, $context);
$url = $generator->generate('foo_placeholder_route', array(
  'id' => 123,
));
           

generate

方法的第一個參數是路由名稱,第二個參數是如果是參數化路由,則可能包含參數的數組。 上面的代碼應生成/basic_routes.php/foo/123 URL。

從YAML檔案加載路由

在上一節中,我們使用

Route

RouteCollection

對象建構了自定義路由。 實際上,

Routing

元件提供了不同的方法來執行個體化路由。 您可以從

YamlFileLoader

XmlFileLoader

PhpFileLoader

類的各種加載器中進行選擇。

在本節中,我們将介紹

YamlFileLoader

加載器,以了解如何從YAML檔案加載路由。

路線YAML檔案

繼續建立具有以下内容的routes.yaml檔案。

foo_route:
    path:     /foo
    defaults: { controller: 'FooController::indexAction' }

foo_placeholder_route:
    path:     /foo/{id}
    defaults: { controller: 'FooController::loadAction' }
    requirements:
        id: '[0-9]+'
           

示例檔案

接下來,繼續制作具有以下内容的load_routes_from_yaml.php檔案。

<?php
require_once './vendor/autoload.php';

use Symfony\Component\Routing\Matcher\UrlMatcher;
use Symfony\Component\Routing\RequestContext;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Generator\UrlGenerator;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\Routing\Loader\YamlFileLoader;
use Symfony\Component\Routing\Exception\ResourceNotFoundException;

try
{
    // Load routes from the yaml file
    $fileLocator = new FileLocator(array(__DIR__));
    $loader = new YamlFileLoader($fileLocator);
    $routes = $loader->load('routes.yaml');

    // Init RequestContext object
    $context = new RequestContext();
    $context->fromRequest(Request::createFromGlobals());

    // Init UrlMatcher object
    $matcher = new UrlMatcher($routes, $context);

    // Find the current route
    $parameters = $matcher->match($context->getPathInfo());

    // How to generate a SEO URL
    $generator = new UrlGenerator($routes, $context);
    $url = $generator->generate('foo_placeholder_route', array(
      'id' => 123,
    ));

    echo '<pre>';
    print_r($parameters);

    echo 'Generated URL: ' . $url;
    exit;
}
catch (ResourceNotFoundException $e)
{
  echo $e->getMessage();
}
           

在這種情況下,唯一不同的是我們初始化路由的方式!

$fileLocator = new FileLocator(array(__DIR__));
$loader = new YamlFileLoader($fileLocator);
$routes = $loader->load('routes.yaml');
           

我們已經使用

YamlFileLoader

加載程式從route.yaml檔案加載路由,而不是直接在PHP本身中對其進行初始化。 除此之外,所有内容都相同,并且應産生與basic_routes.php檔案相同的結果。

多合一路由器

在本節的最後,我們将介紹

Router

類,該類使您可以使用較少的代碼行快速設定路由。

繼續制作具有以下内容的all_in_one_router.php檔案。

<?php
require_once './vendor/autoload.php';

use Symfony\Component\Routing\RequestContext;
use Symfony\Component\Routing\Router;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Generator\UrlGenerator;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\Routing\Loader\YamlFileLoader;
use Symfony\Component\Routing\Exception\ResourceNotFoundException;

try
{
    $fileLocator = new FileLocator(array(__DIR__));

    $requestContext = new RequestContext();
    $requestContext->fromRequest(Request::createFromGlobals());

    $router = new Router(
        new YamlFileLoader($fileLocator),
        'routes.yaml',
        array('cache_dir' => __DIR__.'/cache'),
        $requestContext
    );

    // Find the current route
    $parameters = $router->match($requestContext->getPathInfo());

    // How to generate a SEO URL
    $routes = $router->getRouteCollection();
    $generator = new UrlGenerator($routes, $requestContext);
    $url = $generator->generate('foo_placeholder_route', array(
      'id' => 123,
    ));

    echo '<pre>';
    print_r($parameters);

    echo 'Generated URL: ' . $url;
    exit;
}
catch (ResourceNotFoundException $e)
{
  echo $e->getMessage();
}
           

除了我們執行個體化了

Router

對象以及必要的依賴關系之外,其他所有内容幾乎都是相同的。

$router = new Router(
    new YamlFileLoader($fileLocator),
    'routes.yaml',
    array('cache_dir' => __DIR__.'/cache'),
    $requestContext
);
           

有了它,您可以立即使用Router對象的

match

方法進行路由映射。

$parameters = $router->match($requestContext->getPathInfo());
           

另外,您将需要使用Router對象的

getRouteCollection

方法來擷取路由。

$routes = $router->getRouteCollection();
           

結論

繼續探索“路由”元件中可用的其他選項,我很想聽聽您的想法!

今天,我們探索了Symfony路由元件,該元件使在PHP應用程式中輕松實作路由成為可能。 在此過程中,我們建立了一些示例來示範路由元件的各個方面。

希望您喜歡這篇文章,并随時使用下面的提要發表您的想法!

翻譯自: https://code.tutsplus.com/tutorials/set-up-routing-in-php-applications-using-the-symfony-routing-component--cms-31231