2016-01-20 70 views
2

我有一個控制器將整個請求轉發給另一個控制器。 第一個控制器是Version1Controller,而$this->controller不爲空,使我可以訪問服務。它將請求轉發到服務中定義的GetUserTrialsController,如controller.get_user_trials。在第二個控制器$this->container爲空。 symfony如何失去一半?有什麼方法可以傳遞容器嗎?Symfony 2控制器轉發到另一個控制器時丟失容器

下面是展示行爲

services.yml

services: 
    controller.get_user_trials: 
     class: AppBundle\Controller\GetUserTrialsController 

Version1Controller.php

<?php 
namespace AppBundle\Controller; 

use Symfony\Bundle\FrameworkBundle\Controller\Controller; 
use Symfony\Component\HttpFoundation\Request; 

class Version1Controller extends Controller 
{ 
    public function indexAction(Request $request) 
    { 
     var_dump("V1Controller " . json_encode(is_null($this->container))); 
     return $this->forward("controller.get_user_trials:indexAction"); 
    } 
} 

GetUserTrials.php

<?php 
namespace AppBundle\Controller; 

use Symfony\Bundle\FrameworkBundle\Controller\Controller; 
use Symfony\Component\HttpFoundation\Request; 

class GetUserTrialsController extends Controller 
{ 
    public function indexAction(Request $request) 
    { 
     var_dump("GetUserTrials " . json_encode(is_null($this->container))); 
     return "abc"; 
    } 
} 

輸出的代碼:

string(18) "V1Controller false" 
string(13) "GetUserTrials true" 
abc 
+0

第二個控制器是服務,所以你必須注入容器到該服務。 – malcolm

+0

我希望$ this-> forward能爲我做到這一點嗎?該函數執行此操作 - 返回$ this-> container-> get('http_kernel') - > handle($ subRequest,HttpKernelInterface :: SUB_REQUEST);在我看來,它似乎正在初始化一個新的請求,並且完成了與原來相同的事情?這將包括設置服務容器 –

+2

當控制器以「App:Controller:Action」格式創建時,容器將由框架注入,否則您必須自己動手。如果你希望它是一個服務,你必須安排容器注入(通過監聽器或服務定義)。 – qooplmao

回答

3

只是爲了擴大在什麼@qooplmao說了一下。理解有兩種不同的方式來實例化控制器是很重要的。

最常見的方法是通過指定三部分控制器字符串。像MyBundle:MyController:我的。當遇到類似這樣的字符串時,路由系統確定控制器類,實例化一個新對象,然後調用setContainer來注入容器。

但是,您可以通過使用僅包含兩部分的字符串來將控制器定義爲服務。當你這樣做時,路由系統只需從容器中取出對象而不需要額外的處理。控制器根本不需要容器是完全可能的,因此沒有必要注入容器。

就您的情況而言,只需在您的服務定義中添加對setContainer的調用即可。

services: 
    controller.get_user_trials: 
    class: AppBundle\Controller\GetUserTrialsController 
    calls: [[setContainer, ['@service_container']]] 

而且一切都會好的。或者沒有定義控制器作爲一個服務,只需使用:

$this->forward("AppBundle:GetUserTrials:index"); 

我碰巧喜歡定義控制器作爲服務,但標準方法正常工作在大多數情況下。

+0

感謝您總結評論,現在更清楚。我想我現在將不再使用控制器作爲服務,直到我剝離它們,以使它們不再擴展SF2控制器基類。 –

+0

您當然選擇。我將我的控制器定義爲服務並注入他們需要的特定依賴關係,例如存儲庫。我從來沒有從我的行動方法中的容器中抽取東西。我仍然使用基礎框架類來利用標準的幫助函數。以FOSUserBundle控制器爲例,說明如何不將控制器定義爲服務。 – Cerad