Symfony2服务是否总是需要在捆绑包中声明?

时间:2012-02-08 00:30:03

标签: php model-view-controller symfony bundle

在Symfony2中,服务被定义为[强调我的]:

  

服务是执行任何PHP对象的通用术语   具体任务。服务通常使用“全球”,例如a   数据库连接对象或传递电子邮件的对象。   在Symfony2中,通常从服务器配置和检索服务   服务容器。具有许多解耦服务的应用程序是   据说遵循面向服务的架构。

以“global”为关键词,我看到的如何定义服务的所有示例都在现有的bundle中声明了服务?以下是MartinSikora.com

的示例
<?php
    // Bundle/HelloBundle/Services/MyService.php
    namespace Bundle\HelloBundle\Services;

    class MyService {

        public function sum($n1, $n2) {
            return $n1 + $n2;
        }

    }
?>

然后他在Hello Controller中使用它:

<?php
// Bundle/HelloBundle/Controller/HelloController.php
namespace Bundle\HelloBundle\Controller;

class HelloController extends Controller {

    public function indexAction() {
        $number = $this->get('my_service')->sum(12, 37);
        // this returns 49

        /*
        ...
        */
    }
}
?>

注意他的示例服务如何在标记为“Services”的文件夹中的HelloBundle包内声明。如果“Services”文件夹存储在任何特定捆绑包之外的一个或多个级别,那是不是更好,因为服务是要在整个应用程序中使用的?

  • 这里的最佳做法是什么?
  • 该服务仅适用于HelloBundle Bundle中的控制器吗?
  • 为什么通常这样做?

1 个答案:

答案 0 :(得分:10)

简短回答
不,不需要在捆绑中定义服务。实际的服务类可能存在也可能不存在于捆绑包中 - 它们可能存在于供应商库文件夹中(或其他任何地方)。服务定义虽然通常在包Resources\config\services.yml中定义,但也可以在app/config.yml services下的BlogPostEntityService中定义。

服务只是一个已经在Symfony的依赖注入容器中注册的类。班级本身可以在任何地方生活。

长答案
了解Symfony2中捆绑包的目的非常重要。您的项目的大部分(主要例外是第三方库)由捆绑包组成。有些人喜欢将所有内容放在一个巨大的包中,但我更喜欢将它们用作特定功能的容器(即:用户管理,博客文章管理,资产管理。)

因为bundle应该代表一个功能,所以在bundle中定义一些服务是有意义的。例如,在BlogPostBundle中定义blog_bundle.blog_post_entity_service类很自然。现在,仅仅因为服务包含在一个包中,不会使它变得不那么全局化。如果我将我的服务注册为MyService,我仍然可以从任何其他捆绑包中访问它。

在Martin的例子中,BlogPostEntityService是一个模糊的例子 - 它不像ArrayUtilService那样具体。但是,您可能会创建实用程序服务(即UtilBundle),在这种情况下,您可能需要创建container并将服务存储在那里。

  

这里的最佳做法是什么?

没有确定的答案 - 您可以自行决定在哪里存储服务类。问问自己该服务是否直接处理您的捆绑包所代表的功能 - 如果是,它可能属于捆绑包。如果您计划共享或重用捆绑包,这也是有意义的。

  

该服务仅适用于HelloBundle中的控制器   捆绑?

没有。您可以从任何控制器(或任何MyService识别类)内调用该服务。您还可以将{{1}}注入任何其他服务。