今天,我們将介紹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
接下來,我們需要初始化
RequestContext
對象,該對象儲存目前的請求上下文資訊。 初始化
UrlMatcher
對象時,将需要該對象,
UrlMatcher
我們将進行介紹。
$context = new RequestContext();
$context->fromRequest(Request::createFromGlobals());
初始化 UrlMatcher
對象
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