繁体   English   中英

Symfony2在控制器中可重用的功能

[英]Symfony2 reusable functions in controllers

经过一段时间不知道如何正确地做到这一点,并避免在几个控制器中重复代码,我搜索并再次寻求,但无法找到一个明确的答案。

特别是一个案例,需要计算一个实体完成的几个统计数据。 该计算将用于3个不同的控制器。 在其中两个中,我将展示分解为不同的布局,在第三个,我将使用此数据进行全局计算。 每次计算的业务逻辑,涉及超过100行代码,我将不得不在不同的控制器中三倍。

一个计划可能是:

  • 计算字段完成“数据A”
  • 计算字段完成“数据B”
  • 计算字段完成“数据C”

使用这3个值,我稍后进行总计算。

我能找到的选项是:

知道如何解决这个问题吗?

非常感谢

服务似乎与描述的用法非常相符。

最近,我参与了会计解决方案。 我使用了很多复杂的算法,很快就有很长的方法,甚至尝试优化代码。

服务很容易调用,并且它们的使用可以使控制器更加性感,更轻,并且通过使用与特定操作相对应的分离服务使大方法可读并且更可裁剪。

并且它们可以在其他组件中使用,只要存在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在你的链接中所说的相对应。

DIC主要帮助管理“全局”对象。 控制器不是全局对象。 而且,控制器应尽可能薄。 它主要是模型和视图/模板之间的粘合剂。 因此,如果您需要能够自定义,那么可能意味着您需要重构它们并从中提取业务逻辑。

有关OOP中BaseController的更多信息,

方法很简单,如果你有一行代码在方法中重复两到三次,你就使用一个变量。
对于代码块,您将使用一种方法。 对于控制器它是相同的,如果你有两个或多个相同类型的对象(这里是一个控制器),你应该使用一个AbstractController(或BaseController),移动你的重复方法(当然只有一次),并删除它们来自儿童控制器。

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');
        // ...
    }

}

希望这可以帮助您避免大量重复的代码。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM