在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”文件夹存储在任何特定捆绑包之外的一个或多个级别,那是不是更好,因为服务是要在整个应用程序中使用的?
答案 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}}注入任何其他服务。