使用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/1foo/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组件在应用程序中生成链接。 提供RouteCollectionRequestContext对象,在UrlGenerator允许你建立特定路由链接。

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

generate方法的第一个参数是路由名称,第二个参数是如果是参数化路由,则可能包含参数的数组。 上面的代码应生成/basic_routes.php/foo/123 URL。

从YAML文件加载路由

在上一节中,我们使用RouteRouteCollection对象构建了自定义路由。 实际上, Routing组件提供了不同的方法来实例化路由。 您可以从YamlFileLoaderXmlFileLoaderPhpFileLoader类的各种加载器中进行选择。

在本节中,我们将介绍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

参与评论 您还未登录,请先 登录 后发表或查看评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:编程工作室 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值