Symfony2 控制器中的可重用函数
Symfony2 reusable functions in controllers
一段时间后不知道如何正确地做到这一点,避免在多个控制器中重复代码,我反复搜索,但找不到明确的答案。
具体一个案例,需要计算一个实体完成的几个统计数据。该计算将用于 3 个不同的控制器。
在其中两个中,我将展示分解成不同的布局,在第三个中,我将使用这些数据进行全局计算。
每次计算的业务逻辑,涉及到100多行代码,我不得不在不同的控制器中增加三倍。
方案可以是:
- 计算字段已完成"Data A"
- 计算字段已完成"Data B"
- 计算字段已完成"Data C"
有了这3个值,我在后面做总计。
我能找到的选项是:
- 将控制器定义为服务,以便稍后在其他控制器中重用,但我不清楚这是否是一个好的做法,这里有一篇分析这个问题的好文章 Symfony2: Make my Controllers Services?
- 一方面How to Define Controllers as Services
- 另一方面是对 Fabien Potencier 的评论 Mention best practice "controller as a service" in chapter Controller # 457 and The 'New' symfony Best Practices
- 创建一个抽象的BaseController。说到这里,但是思路没有展开。Symfony2 and be DRY approach in controllers
知道如何解决这种情况吗?
非常感谢
服务似乎与描述的用法非常对应。
最近,我在研究会计解决方案。我使用了很多复杂的算法,很快我就有了很长的方法,甚至试图优化代码。
服务很容易调用,它们的使用可以使控制器更性感、更轻巧,并通过使用与特定操作相对应的单独服务使大方法更易读和更易切割。
并且它们可以在其他组件中使用,只要存在 DependencyInjection,如果您可能需要在控制器的另一个上下文中应用它,那么移动您的逻辑就足够了。
声明起来很简单:
services:
acmeapp.calculation:
class: Acme\AppBundle\Services\CalculationService
arguments: ["@doctrine.orm.entity_manager", "@acmeapp.anotherservice"]
和服务
class CalculationService {
protected $em;
protected $another;
public function __constructor(EntityManager $entityManager, AnotherService $anotherService)
{
$this->em = $entityManager;
$this->another = $anotherService;
}
//...
}
Controller-Service 方法主要是一种服务,具有其所有优点。
您的服务方法可以呈现视图并使用 _controller
属性关联路由,如下所示:
display_data_a:
path: /data/A
methods: GET
defaults: { _controller: acmeapp.calculation:dealWithData }
无需从 Symfony\Bundle\FrameworkBundle\Controller\Controller
扩展您的服务,但是,您当然可以使用它。
此外,如果您的控制器之间有许多重复的代码且具有一些不同的字符,那么抽象 BaseController
可能是一个非常干净的替代方案。
这就是我在使用服务之前所做的,如果这些方法与我对控制器的定义相对应,这与@fabpot 在您的 link.
中所说的相对应
The DIC mostly helps manage "global" objects. Controllers are not global objects. Moreover, a controller should be as thin as possible. It's mainly the glue between your Model and the View/Templates. So, if you need to be able to customize then, it probably means that you need to refactor them and extract the business logic from them.
更多关于 OOP 中的 BaseController,
方法很简单,如果你有一行代码在一个方法中重复了两三次,你就用一个变量。
同样对于一段代码,您将使用一个方法。
对于控制器,它是相同的,如果您有两个或多个相同类型的对象(这里是一个控制器),您应该使用一个 AbstractController(或 BaseController),将重复的方法移动到其中(当然只有一次),然后删除它们来自子控制器。
基础控制器:
class BaseController extends Controller
{
/**
* Shortcut for get doctrine entity manager.
*/
public function getEntityManager()
{
return $this->getDoctrine->getEntityManager();
}
/**
* Shortcut for locate a resource in the application.
*/
public function locateResource($path)
{
return $this->get('kernel')->locateResource($path);
}
// ...
}
并将其用作子控制器的一部分
class ChildController extends BaseController
{
public function helloAction()
{
$em = $this->getEntityManager();
$file = $this->locateResource('@AcmeAppBundle/Resources/config/hello.yml');
// ...
}
}
希望这可以帮助您避免大量重复代码。
一段时间后不知道如何正确地做到这一点,避免在多个控制器中重复代码,我反复搜索,但找不到明确的答案。
具体一个案例,需要计算一个实体完成的几个统计数据。该计算将用于 3 个不同的控制器。 在其中两个中,我将展示分解成不同的布局,在第三个中,我将使用这些数据进行全局计算。 每次计算的业务逻辑,涉及到100多行代码,我不得不在不同的控制器中增加三倍。
方案可以是:
- 计算字段已完成"Data A"
- 计算字段已完成"Data B"
- 计算字段已完成"Data C"
有了这3个值,我在后面做总计。
我能找到的选项是:
- 将控制器定义为服务,以便稍后在其他控制器中重用,但我不清楚这是否是一个好的做法,这里有一篇分析这个问题的好文章 Symfony2: Make my Controllers Services?
- 一方面How to Define Controllers as Services
- 另一方面是对 Fabien Potencier 的评论 Mention best practice "controller as a service" in chapter Controller # 457 and The 'New' symfony Best Practices
- 创建一个抽象的BaseController。说到这里,但是思路没有展开。Symfony2 and be DRY approach in controllers
知道如何解决这种情况吗?
非常感谢
服务似乎与描述的用法非常对应。
最近,我在研究会计解决方案。我使用了很多复杂的算法,很快我就有了很长的方法,甚至试图优化代码。
服务很容易调用,它们的使用可以使控制器更性感、更轻巧,并通过使用与特定操作相对应的单独服务使大方法更易读和更易切割。
并且它们可以在其他组件中使用,只要存在 DependencyInjection,如果您可能需要在控制器的另一个上下文中应用它,那么移动您的逻辑就足够了。
声明起来很简单:
services:
acmeapp.calculation:
class: Acme\AppBundle\Services\CalculationService
arguments: ["@doctrine.orm.entity_manager", "@acmeapp.anotherservice"]
和服务
class CalculationService {
protected $em;
protected $another;
public function __constructor(EntityManager $entityManager, AnotherService $anotherService)
{
$this->em = $entityManager;
$this->another = $anotherService;
}
//...
}
Controller-Service 方法主要是一种服务,具有其所有优点。
您的服务方法可以呈现视图并使用 _controller
属性关联路由,如下所示:
display_data_a:
path: /data/A
methods: GET
defaults: { _controller: acmeapp.calculation:dealWithData }
无需从 Symfony\Bundle\FrameworkBundle\Controller\Controller
扩展您的服务,但是,您当然可以使用它。
此外,如果您的控制器之间有许多重复的代码且具有一些不同的字符,那么抽象 BaseController
可能是一个非常干净的替代方案。
这就是我在使用服务之前所做的,如果这些方法与我对控制器的定义相对应,这与@fabpot 在您的 link.
The DIC mostly helps manage "global" objects. Controllers are not global objects. Moreover, a controller should be as thin as possible. It's mainly the glue between your Model and the View/Templates. So, if you need to be able to customize then, it probably means that you need to refactor them and extract the business logic from them.
更多关于 OOP 中的 BaseController,
方法很简单,如果你有一行代码在一个方法中重复了两三次,你就用一个变量。
同样对于一段代码,您将使用一个方法。
对于控制器,它是相同的,如果您有两个或多个相同类型的对象(这里是一个控制器),您应该使用一个 AbstractController(或 BaseController),将重复的方法移动到其中(当然只有一次),然后删除它们来自子控制器。
基础控制器:
class BaseController extends Controller
{
/**
* Shortcut for get doctrine entity manager.
*/
public function getEntityManager()
{
return $this->getDoctrine->getEntityManager();
}
/**
* Shortcut for locate a resource in the application.
*/
public function locateResource($path)
{
return $this->get('kernel')->locateResource($path);
}
// ...
}
并将其用作子控制器的一部分
class ChildController extends BaseController
{
public function helloAction()
{
$em = $this->getEntityManager();
$file = $this->locateResource('@AcmeAppBundle/Resources/config/hello.yml');
// ...
}
}
希望这可以帮助您避免大量重复代码。