Symfony2在控制器中可重用的函数 [英] Symfony2 reusable functions in controllers

查看:163
本文介绍了Symfony2在控制器中可重用的函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



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



一个方案可以是: p>


  • 计算字段已完成数据A

  • 计算字段已填写完毕数据B

  • 计算字段完成数据C



对于这3个值,我稍后进行总计算。 p>

我可以找到的选项是:




  • 定义控制器作为服务重用以后在其他控制器,但我不清楚是否是一个好的做法,这里是一个很好的文章分析这个问题 Symfony2:使我的控制器服务?



    任何想法如何解决这种情况?



    $ b

    解决方案

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



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



    服务很容易调用,他们的使用可以使控制器这么多,更轻,并且通过使用对应于特定动作的分开的服务来使得大的方法可读和更容易。



    并且它们可以用于其他组件,只要DependencyInjection存在,这是一个足够的理由来移动你的逻辑,如果你可能需要在控制器的另一个上下文中应用它。



    很容易声明它:

     服务:
    acmeapp.calculation:
    类:Acme\AppBundle\Services\CalculationService
    参数: @ doctrine.orm.entity_manager,@ acmeapp.anotherservice]

    p>

     类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
    方法:GET
    默认值:{_controller:acmeapp.calculation:dealWithData}

    Symfony \Bundle\FrameworkBundle\Controller\Controller ,但是,当然,你可以使用它。



    此外,如果您的控制器之间有多个不同字符的复制代码,抽象 BaseController 可能是一个非常干净的替代方法。

    这是我在使用服务之前,如果方法对应于我的定义一个控制器,这是对应的@fabpot在你的链接中说的。


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


    更多关于OOP中的BaseController,



    方法很简单,如果你有一行代码在一个方法中重复两次或三次, 。

    与一块代码相同,您将使用一种方法。
    对于控制器,如果你有两个或多个相同类型的对象(这里是一个控制器),你应该使用一个AbstractController(或BaseController),移动你的重复方法(当然只有一次) ,并从子控制器中删除它们。



    BaseController:

      class BaseController extends Controller 
    {
    / **
    *获取doctrine实体管理器的快捷方式。
    * /
    public function getEntityManager()
    {
    return $ this-> getDoctrine-> getEntityManager();
    }

    / **
    *在应用程序中查找资源的快捷方式。
    * /
    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');
    // ...
    }

    }

    希望这有助于避免大量的重复代码。


    After some time without knowing how to do this properly, and avoid duplicating code in several controllers, I searched and again to seek, but can not find a clear answer.

    One case in particular, need to calculate several statistics data completed of an entity. This calculation will use in 3 different controllers. In two of them, I'll show broken down into different layouts, and on the third, I will use this data to make a global calculation. business logic for each calculation, involves more than 100 lines of code, I would have to triple in the different controllers.

    A scheme could be:

    • Calculation fields completed "Data A"
    • Calculation fields completed "Data B"
    • Calculation fields completed "Data C"

    With these 3 values, I make a later total calculation.

    The options that I could find are:

    Any idea how to solve this scenario?

    thanks a lot

    解决方案

    The Services seem to be much corresponding with the described usage.

    Recently, I worked on an accounting solution. I used a lot of complex algorithms and I soon had very long methods, even trying to optimise code.

    Services are easily callable, and their usage can make controllers so much sexier, lighter, and make big methods readable and more cuttable by using separated services corresponding to specific actions.

    And they can be used in other components, as long as DependencyInjection is present, it's a sufficient raison to move your logic if you may need apply it in another context that a controller.

    It's simple to declare it :

    services:
        acmeapp.calculation:
            class: Acme\AppBundle\Services\CalculationService
            arguments: ["@doctrine.orm.entity_manager", "@acmeapp.anotherservice"]
    

    And the service

    class CalculationService {
    
        protected $em;
        protected $another;
    
        public function __constructor(EntityManager $entityManager, AnotherService $anotherService)
        {
            $this->em = $entityManager;
            $this->another = $anotherService;
        }
    
        //...
    }
    

    The Controller-Service approach is primarily a service, with all its advantages.
    A method of your service can render a view and have a route associated using the _controller attribute, like this :

    display_data_a:
        path:     /data/A
        methods: GET
        defaults: { _controller: acmeapp.calculation:dealWithData }
    

    Without extending your service from the Symfony\Bundle\FrameworkBundle\Controller\Controller, but, of course, you can use it.

    Also, an abstract BaseController can be a very clean alternative, if you have many duplicated code with a few different characters between your controllers.
    It's what I'm doing before use services, if the methods are corresponding with my definition of a controller, which is corresponding to what @fabpot says in your 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.

    More about BaseController in OOP,

    The way is simple, if you have a line of code that repeats itself two or three times in a method, you use a variable.
    Same for a block of code, you will use a method. For controllers it's the same, if you have two or more objects of the same type (here a controller), you should use an AbstractController (or BaseController), move your duplicated methods in it (only once, of course), and remove them from the child controllers.

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

    And use it as part of your child controllers

    class ChildController extends BaseController
    {
        public function helloAction()
        {
            $em = $this->getEntityManager();
            $file = $this->locateResource('@AcmeAppBundle/Resources/config/hello.yml');
            // ...
        }
    
    }
    

    Hope this helps you to avoid a lot of a duplicated code.

    这篇关于Symfony2在控制器中可重用的函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆