【问题标题】:Symfony router call controllerSymfony 路由器呼叫控制器
【发布时间】:2018-08-15 14:46:32
【问题描述】:

我正在编写自己的项目并想使用一些 Symfony 组件。 我正在为我的项目实施 Sf 路由器,但我不明白如何在路由器中调用控制器。

例如,我有一门课:

<?php

namespace App;

use Symfony\Component\Config\FileLocator;
use Symfony\Component\Routing\Loader\YamlFileLoader;
use Symfony\Component\Routing\Matcher\UrlMatcher;
use Symfony\Component\Routing\RequestContext;
use Symfony\Component\HttpFoundation as Http;
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;

class AppRouter
{
    public function match() {
        $context = new RequestContext();
        $request = Http\Request::createFromGlobals();
        $context->fromRequest($request);
        $matcher = new UrlMatcher($this->getRoutes(), $context);
        return $matcher->matchRequest($request);
    }

    private function getRoutes() {
        $fileLocator = new FileLocator([__DIR__ . '/../config']);
        $loader = new YamlFileLoader($fileLocator);
        $routes = $loader->load('routes.yml');
        return $routes;
    }
}

我的routes.yml 中有一些已定义的路由,所以如果我尝试去注册路由match() 方法返回给我一个如下所示的数组:

[
  "_controller" => "Controller\\MyController::testAction"
  "_route" => "test"
]

那么,我现在如何调用控制器以获取匹配的 URL?我已阅读文档,但不明白我应该如何执行此操作。

【问题讨论】:

  • 您需要养成accepting answers 的习惯,它可以帮助您解决问题。您将获得积分,并鼓励其他人帮助您。
  • 顺便说一句 - 不要在这里对其他人无礼,就像您在删除的问题中一样,除非您想获得一次被禁营地的旅行。
  • "if you what just to spam in comments just f*ck off pls" - 我真的不应该这样,你完全不合时宜。这来自您的now deleted post。你可以把这些话放在外屋里。你认为“请”是“礼貌”吗?哇。
  • 并停止浸泡每个人并成为社区的好成员。你来这里是为了解决你的小问题然后离开;有钱。

标签: symfony


【解决方案1】:

这是一个比看起来要复杂得多的问题。

最简单的方法是简单地分解 _controller 字符串,新建控制器并调用操作。

// Untested but I think the syntax is correct
$matched = $router->match();
$parts = explode(':',$matched['_controller']);
$controller = new $parts[0]();
$controller->$parts[2]();

当然还有大量的错误检查要添加。

我之所以说它可能更复杂,是因为实际上你可以做的事情还有很多。看看 HTTP 组件。 HttpKernel::handle($request) 使用 ControllerResolver 类来创建控制器以及 ArgumentResolver 来处理控制器的许多参数。有趣的东西。

Create Your Own Framework 是一个很好的资源。

相当新的 Symfony Flex 方法为您提供了一个简单的框架,也值得研究。

【讨论】:

    【解决方案2】:

    接下来是我的解决方案:

    1. 稍微改变一下我的 routes.yml 参数:没有类名只包含斜杠
    2. 使用call_user_func_array($this-&gt;controller, $this-&gt;parameters)

    【讨论】:

      【解决方案3】:

      HTTP 内核处理路由到控制器调用。你可以找到完整的文档here

      控制器解析器和参数解析器将帮助您轻松地将路由匹配到控制器方法。这是一种简单而可靠的方法,可以让路由器在遗留项目上启动并运行,而无需调用完整的框架。

      再想一想:我们的框架比以往任何时候都更健壮、更灵活,但它仍然只有不到 50 行代码。

      require_once __DIR__.'/../vendor/autoload.php';
      use Symfony\Component\HttpFoundation\Request;
      use Symfony\Component\HttpFoundation\Response;
      use Symfony\Component\Routing;
      use Symfony\Component\HttpKernel;
      
      function render_template(Request $request)
      {
          extract($request->attributes->all(), EXTR_SKIP);
          ob_start();
          include sprintf(__DIR__.'/../src/pages/%s.php', $_route);
      
          return new Response(ob_get_clean());
      }
      
      $request = Request::createFromGlobals();
      $routes = include __DIR__.'/../src/app.php';
      
      $context = new Routing\RequestContext();
      $context->fromRequest($request);
      $matcher = new Routing\Matcher\UrlMatcher($routes, $context);
      
      $controllerResolver = new HttpKernel\Controller\ControllerResolver();
      $argumentResolver = new HttpKernel\Controller\ArgumentResolver();
      
      try {
          $request->attributes->add($matcher->match($request->getPathInfo()));
      
          $controller = $controllerResolver->getController($request);
          $arguments = $argumentResolver->getArguments($request, $controller);
      
          $response = call_user_func_array($controller, $arguments);
      } catch (Routing\Exception\ResourceNotFoundException $exception) {
          $response = new Response('Not Found', 404);
      } catch (Exception $exception) {
          $response = new Response('An error occurred', 500);
      }
      
      $response->send();
      

      `

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-08-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-05-22
        相关资源
        最近更新 更多