2012-03-12 35 views
4

我現在正在開發我的第一個symfony2項目。我創建了一個服務,我需要爲每個控制器調用它來生成一個在我的網站的所有頁面中都必需的html。何處爲symfony2中的所有頁面放置通用業務邏輯

所以我創建了一個擴展了Symfony \ Bundle \ FrameworkBundle \ Controller \ Controller類的BaseController類,並試圖將代碼放置在這個BaseController類中。現在,每當我從構造函數中調用:

$my_service = $this->get('my_service'); 

$my_service = $this->container->get('my_service'); 

我得到錯誤:

Call to a member function get() on a non-object. 

容器對象尚未初始化。這個問題的解決方案是什麼?如果我想在所有包含動態數據的頁面中放置左面板或標題,symfony2中如何遵循DRY方法?

在此先感謝。

+0

你在'confil.yml'中註冊了那個服務嗎?它可以通過導入或方向聲明來完成... – 2012-03-12 17:13:05

回答

5

你不應該使用構造函數在你的控制器類,尤其是當你從Symfony的控制器繼承:這樣,你得到的容器對象實例化後(DIC將調用來自Symfony的的控制器繼承了setContainer方法)。

通常,對於您的第一個實驗,請在操作方法中使用服務;如果您需要在每個請求中執行一些交叉邏輯,則可以考慮註冊一些事件偵聽器(請參閱Symfony網站中的「Internals」文檔)。

當您對框架更有信心時,您可以開始考慮不繼承Symfony的控制器,在DIC中註冊控制器類並手動注入您需要的服務(最終在構造函數中實現一些邏輯)。

+0

感謝Aldo,事件監聽器似乎是解決此問題的最佳解決方案。我已經看過它。看起來我需要爲事件'GetResponseEvent'創建一個監聽器類。但我無法添加一些變量,這些變量將被髮送到查看進行渲染。你能給我一個例子代碼來做到這一點? – sumanchalki 2012-03-13 05:44:37

+0

我認爲當你攔截響應事件時,模板已經被評估爲它們的字符串表示(封裝在響應對象中);如果我是對的,那不適合爲視圖注入變量。我會嘗試使用kernel.request事件並將變量附加到請求對象(您可以使用app.request.get('attrib')helper在視圖中訪問它們)。更高級的你可以使用kernel.view事件並且在你的監聽器中提供模板來附加最終的變量。 – 2012-03-13 10:12:30

+0

gr8 ...我會盡力... – sumanchalki 2012-03-17 11:41:36

4

我知道這不是你想要的答案,但是如果你在所有頁面上都需要一些html,我認爲使用服務的方式是錯誤的。

我想你知道關於樹枝和使用佈局來放置通用代碼的可能性。但你也可以嵌入控制器:

{% render "AcmeArticleBundle:Article:recentArticles" %} 

內recentArticlesAction,您可以將您的特定代碼,並返回一個模板。通過這個,你可以在你的每個模板中獲得自定義的html!有關更多信息,請參閱symfony文檔:http://symfony.com/doc/current/book/templating.html#embedding-controllers

+0

感謝您的意見。我只是想通過這種方式,我將爲通用目的製造控制器(比如說計算標題或右側面板數據),並按照本示例中的描述渲染它的操作;因爲我不使用樹枝,我認爲這也可以使用PHP引擎完成。 – sumanchalki 2012-03-13 05:37:47

+0

看看我發佈的鏈接。在每個代碼示例上方,您可以看到用於不同語言的開關。在那裏你可以看到如何將控制器嵌入到php模板中! – Sgoettschkes 2012-03-13 08:51:38

0

業務邏輯是您爲應用程序編寫的所有自定義代碼,並非特定於框架(例如路由和控制器)。用作服務的域類,Doctrine實體和常規PHP類是業務邏輯的很好例子。 Ref