【问题标题】:The controller for URI is not callable, using annotationsURI 的控制器不可调用,使用注解
【发布时间】:2014-03-26 09:02:48
【问题描述】:

我有一个返回 500 的 symfony2 控制器,带有以下日志条目:

[2014-03-26 01:25:48] request.INFO: Matched route "searchtempestsite_direct_sponsored" (parameters: "_controller": "SearchTempest\Bundle\SiteBundle\Controller\SearchController::DirectResultsSponsoredAction", "_route": "searchtempestsite_direct_sponsored") [] []
[2014-03-26 01:25:48] request.CRITICAL: Uncaught PHP Exception InvalidArgumentException: "The controller for URI "/search/direct/sponsored" is not callable." at [...]/releases/20140326082503/vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Controller/ControllerResolver.php line 82 {"exception":"[object] (InvalidArgumentException: The controller for URI \"/search/direct/sponsored\" is not callable. at [...]/releases/20140326082503/vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Controller/ControllerResolver.php:82)"} []

控制器动作定义为

/**
 * Display the Sponsored Results frame in Direct Results
 *
 * @return Symfony\Component\HttpFoundation\Response
 *
 * @Route("/search/direct/sponsored", name="searchtempestsite_direct_sponsored")
 */
public function DirectResultsSponsoredAction()
{
    $response = $this->get('legacy_bridge')
        ->request('direct_sponsored.php');

    $parameters = $response->getTemplateParameterBag();
    $content = $this->renderView(
        'SearchTempestSiteBundle:Search:directSponsored.html.twig',
        $parameters->all()
    );
    $response->setContent($content);

    return $response;
}

奇怪的是,在我的本地测试服务器上,无论是开发模式还是产品模式,一切都正常运行。只有当我尝试使用 capifony 将其部署到生产服务器时,我才会收到此错误。但是,在同一控制器下定义的所有其他路由都正常工作。只有这个新的失败了。这是一条工作路线:

/**
 * Display the Direct Results index
 *
 * @return Symfony\Component\HttpFoundation\Response
 *
 * @Route("/search/direct", name="searchtempestsite_direct")
 */
public function DirectResultsAction()
{
    $response = $this->get('legacy_bridge')
        ->request('adv_control.php');

    $parameters = $response->getTemplateParameterBag();

    $content = $this->renderView(
        'SearchTempestSiteBundle:Search:directResults.html.twig',
        $parameters->all()
    );
    $response->setContent($content);

    return $response;
}

我已尝试更改路线(从 /search/direct/赞助到 /search/direct_赞助),但在新路径上我仍然收到相同的 500 错误。 (当然是错误中的新路径。)

除此之外,我在尝试什么方面有点卡住了,没有深入研究 Symfony 和 Sensio 代码的核心来追踪它是如何协调这些注释的。大概这与安装到服务器有关,因为它在本地工作,但据我所知,一切都应该是一样的。两者都使用 composer 来安装依赖项,因此所有供应商代码都应该相同。我们不会在服务器的版本之间共享缓存,因此它使用的是新缓存。 (Capifony 确实调用了应用程序/控制台缓存:warmup --env=prod。)

听起来这个错误通常是由于路由 yml 中的控制器规范与 Action 函数的名称不匹配,或者该函数不是公共的。此处均不适用。

我很乐意提供所需的任何其他信息。

编辑:它现在可以工作了,虽然我没有改变任何东西。我认为发生了什么与 Capifony 的 multistage extension 有关。我们正在运行三个阶段(开发、测试、产品)。我一直在开发阶段对此进行测试,但一时兴起,我尝试将其部署到其他阶段,看看这是否会产生任何影响。一开始并没有,但是在我部署到所有三个之后,当我重新部署到其中任何一个时,路由就开始工作了。

编辑 2:多阶段是主要问题,但还有更多问题。请参阅下面的答案。

【问题讨论】:

  • 你试过rm -rf app/cache/*然后php app/console router:debug吗? (在您的服务器上,当然在 env prod 中)
  • 您开发和部署的操作系统是什么?
  • 是的,它在清除缓存目录之前和之后列出:searchtempestsite_direct_support ANY ANY ANY /search/direct/owned
  • @JakubZalas 这确实是一个区别。在 Windows 上开发并部署到 CentOS。不要认为这是这里的问题..它现在正在工作;将使用更多信息编辑我的帖子。

标签: symfony capifony


【解决方案1】:

原来问题出在 ApcClassLoader 上。 app.php 中的这两行指示 sf2 使用 APC 来缓存应用程序使用的各种类的位置(文件系统路径):

$loader = new ApcClassLoader('sf2', $loader);
$loader->register(true);

您应该将 sf2 更改为唯一前缀以避免缓存键冲突。我们这样做了,但是对我们的每个阶段都使用了相同的“唯一”前缀,这意味着当我们运行部署并清除 apc 缓存时,首先访问的阶段将设置缓存中的文件位置,以及那些相同的文件然后将用于所有阶段。由于它是一个繁忙的站点,这意味着生产阶段文件最终被用于其他阶段。

解决方案应该是为每个阶段简单地部署一个单独的 app.php 版本,并带有单独的前缀。 (或者为前缀传递一个变量;但是你想这样做。)但是,我还发现同一阶段的先前版本偶尔会污染缓存,即使我们清除了 APC 缓存([如此处所述][1]) 部署后立即。我目前无法解释为什么会发生这种情况,因为即使我们在清除之前添加延迟,它似乎也会发生,以防有任何请求正在进行中。

所以现在,我们将简单地使用 composer 而不是 apc 来保存类映射,如此处“使用 Composer 的类映射功能”部分所述:http://symfony.com/doc/current/book/performance.html

编辑:啊,这解释了最后一点,即使在新版本发布之后,早期版本如何污染缓存:https://stackoverflow.com/a/23419954/160565。我们使用符号链接进行部署,而 PHP 正在缓存旧的符号链接路由,导致之前的部署在符号链接更新之前重新填充缓存。那里链接的答案解释了如何解决这个问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-06-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-16
    • 2013-10-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多