2014-03-24 21 views
1

由於我從Symfony 2.1升級到2.4,我遇到了一個非常意外的錯誤。現在我只能推測它發生的原因:從2.4開始的Ajax服務錯誤:自定義事件+請求範圍

[2014-03-24 10:32:19] emergency.EMERGENCY: Uncaught exception 'Symfony\Component\DependencyInjection\Exception\InactiveScopeException' with message 'You cannot create a service ("form.type.daterange") of an inactive scope ("request").' in D:\Users\abousquet\workspace\eportal\app\cache\dev\appDevDebugProjectContainer.php:1231 
Stack trace: 
#0 D:\Users\abousquet\workspace\eportal\app\bootstrap.php.cache(2033): appDevDebugProjectContainer->getForm_Type_DaterangeService() 
#1 D:\Users\abousquet\workspace\eportal\app\cache\dev\classes.php(1842): Symfony\Component\DependencyInjection\Container->get('form.type.dater...') 
#2 D:\Users\abousquet\workspace\eportal\app\cache\dev\classes.php(1807): Symfony\Component\EventDispatcher\ContainerAwareEventDispatcher->lazyLoad('resources.autol...') 
#3 D:\Users\abousquet\workspace\eportal\vendor\symfony\symfony\src\Symfony\Component\HttpKernel\Debug\TraceableEventDispatcher.php(106): Symfony\Component\EventDispatcher\ContainerAwareEventDispatcher->getListeners(NULL) 
#4 D:\Users\abousquet\workspace\eportal\vendor\symfony\sy {"type":1,"file":"D:\\Users\\abousquet\\workspace\\eportal\\app\\cache\\dev\\appDevDebugProjectContainer.php","line":1231} [] 

每當我嘗試使用Ajax訪問任何頁面時,DEV中觸發該錯誤。它在頁面呈現後觸發(控制器的動作正確完成並且錯誤發生之後)。這使得很難理解錯誤產生的時間。

服務form.type.dateRange是一種自定義表單類型,它也被註冊爲事件訂戶。下面是它的服務定義:

<service id="form.type.dateRange" class="eportal\CoreBundle\Form\DateRangeType" scope="request"> 
    <argument type="service" id="calendar.conf.reader" /> 
    <tag name="form.type" alias="dateRange" /> 
    <tag name="kernel.event_subscriber" /> 
</service> 

此服務被註冊自定義事件resources.autoload,則觸發我的主控制器頁面呈現之前 - 但使用Ajax的網頁時,從來沒有。

正如日誌所說,看起來請求服務在請求此服務時不可用。但是什麼時候以及爲什麼要求它?在我看來,消除這個神祕的電話會解決我的問題。

如果我取消訂閱事件註冊,或者如果我擴大範圍,則錯誤不會彈出。我堅信自定義事件+請求範圍的組合是我的問題的根源。

當我阻止form.type.dateRange上的錯誤時,在相同範圍的同一事件上註冊的某個其他服務會失敗。因此,我的班級裏的編碼錯誤似乎對我來說不太可能。

上次有趣的事實:當實際使用這些失敗的服務時,錯誤會在頁面上觸發。

編輯:哪裏是觸發了我的自定義事件

代碼。這是的覆蓋渲染()方法

abstract class HTMLControllerAbstract extends CoreControllerAbstract 
{ 
    ... 

    public function render($view, array $parameters = array(), Response $response = null) 
    { 
     $event = new FilterControllerEvent(
      $this->get('kernel'), 
      array($this, 'render'), 
      $this->getRequest(), 
      HttpKernelInterface::MASTER_REQUEST 
     ); 

     $this->get('event_dispatcher')->dispatch(StoreEvents::RESOURCES_AUTOLOAD, $event); 

     $this->setReplacement('breadcrumb', $this->breadcrumb->getView()); 
     $this->setReplacement('javascripts', $this->javascriptResources); 
     $this->setReplacement('stylesheets', $this->CSSResources); 
     $this->setReplacement('see_also', $this->_getSeeAlso()); 

     return parent::render($view, $parameters, $response); 
    } 

    ... 
} 

編輯:

什麼工作:取下使用自定義事件的所有服務的「請求」範圍。沒有錯誤會被記錄,但我仍然擔心連續兩頁被處理相同的請求服務實例。

我仍然覺得解決方案有點不滿意。沒有明確的理由說明爲什麼請求作用域會因自定義事件失敗。

接受響應:

正如我懷疑,這個問題在一個隱藏子呼叫,我仍然不能完全弄清楚今天的發生。解決方案?由提供的解決方案Manolo Salsas最終是正確的,但我當時不知道應該在哪寫這兩個loc。現在我知道,它必須在app/AppKernel中。PHP:

class AppKernel extends Kernel 
{ 
    ... 

    public function registerBundles() 
    { 
     ... 
    } 

    public function registerContainerConfiguration(LoaderInterface $loader) 
    { 
     ... 
    } 

    protected function initializeContainer() 
    { 
     parent::initializeContainer(); 
     $this->getContainer()->enterScope('request'); 
     $this->getContainer()->set('request', new \Symfony\Component\HttpFoundation\Request(), 'request'); 
    } 
} 

適用於我的特殊情況另一種解決方案,是讓從崩潰的表單類型擺脫要求參數。由於該請求被用於自動填充一些表單選項,因此解決方案是手動填充這些選項,而不是從預訂自定義事件的服務的任何地方填充這些選項。

+0

你只在開發環境中得到這個錯誤?這可能是由於調試工具欄。你能否嘗試關掉調試工具欄並檢查它的原因? – vishal

+0

我也有類似的錯誤http://stackoverflow.com/questions/17942738/error-you-cannot-create-a-service-templating-helper-assets-of-an-inactive-s – vishal

+0

雖然你的推理不知何故是有道理的,禁用工具欄不會解決任何問題。我看到了你的錯誤和你接受的答案,但我不明白更正發生在哪裏。據我所知,我的問題在CLI中不會發生。 – Zephyr

回答

0

如果您要訪問的Request對象,你可以擴展ContainerAware和:

$this->getContainer()->enterScope('request'); 
$this->getContainer()->set('request', new Request(), 'request'); 
+0

如果出現問題,應用程序將徹底崩潰。無論如何檢查,但錯誤仍然在這裏。 – Zephyr

+0

@Zephyr - 你說得對。試試這個。 – Manolo

+0

@Zephyr - 對不起。我又錯了。更新的答案應該可以工作。 – Manolo