Where to place business logic in Symfony2?

symfony abstractcontroller
symfony app
symfony cookbook
symfony var
symfony documentation
symfony application class
symfony project structure
symfony class variables

After reading a lot of posts and Stack Overflow resources, I've still got some problems about the famous question about "where to put business logic?" Reading StackOverflow Question and A Blog Post, I believe I've understood the issue of code separation well.

Suppose I have a web form where you can add a user that will be added to a db. This example involves these concepts:

  • Form
  • Controller
  • Entity
  • Service
  • Repository

If I didn't miss something, you have to create an entity with some properties, getters, setters and so on in order to make it persist into a db. If you want to fetch or write that entity, you'll use entityManager and, for "non-canonical" query, entityRepository (that is where you can fit your "query language" query).

Now you have to define a service (that is a PHP class with a "lazy" instance) for all business logic; this is the place to put "heavy" code. Once you've recorded the service into your application, you can use it almost everywhere and that involves code reuse and so on.

When you render and post a form, you bind it with your entity (and with constraints of course) and use all the concepts defined above to put all together.

So, "old-me" would write a controller's action in this way:

public function indexAction(Request $request)
    {
        $modified = False;
        if($request->getMethod() == 'POST'){ // submit, so have to modify data
            $em = $this->getDoctrine()->getEntityManager();
            $parameters = $request->request->get('User'); //form retriving
            $id = $parameters['id'];
            $user = $em->getRepository('SestanteUserBundle:User')->find($id);
            $form = $this->createForm(new UserType(), $user);
            $form->bindRequest($request);
            $em->flush();
            $modified = True;
        }

        $users = $this->getDoctrine()->getEntityManager()->getRepository('SestanteUserBundle:User')->findAll();
        return $this->render('SestanteUserBundle:Default:index.html.twig',array('users'=>$users));
    }

"New-me" has refactored code in this way:

   public function indexAction(Request $request)
    {
        $um = $this->get('user_manager');
        $modified = False;
        if($request->getMethod() == 'POST'){ // submit, so have to modify data
            $user = $um->getUserById($request,False);
            $form = $this->createForm(new UserType(), $user);
            $form->bindRequest($request);
            $um->flushAll();
            $modified = True; 
        }
        $users = $um->showAllUser();
        return $this->render('SestanteUserBundle:Default:index.html.twig',array('users'=>$users));
    }

Where $um is a custom service where all code that you can't see from #1 code piece to #2 code piece is stored.

So, here are my questions:

  1. Did I, finally, get the essence of symfony2 and {M}VC in general?
  2. Is the refactor a good one? If not, what would be a better way?

Post Scriptum: I know that I can use the FOSUserBundle for User store and authentication, but this is a basic example for teach myself how to work with Symfony. Moreover, my service was injected with ORM.Doctrine.* in order to work (just a note for who read this question with my same confusion)

There are two main approaches regarding on where to put the business logic: the SOA architecture and the domain-driven architecture. If your business objects (entities) are anemic, I mean, if they don’t have business logic, just getters and setters, then you will prefer SOA. However, if you build the business logic inside your business objects, then you will prefer the other. Adam Bien discusses these approaches:

Domain-driven design with Java EE 6: http://www.javaworld.com/javaworld/jw-05-2009/jw-05-domain-driven-design.html

Lean service architectures with Java EE 6: http://www.javaworld.com/javaworld/jw-04-2009/jw-04-lean-soa-with-javaee6.html

It’s Java, but you can get the idea.

model view controller, Now you have to define a service (that is a PHP class with a "lazy" instance) for all business logic; this is the place to put "heavy" code. Namespaces and organizing business logic services in Symfony I want to talk about namespacing services in Symfony, specifically Symfony3. These are exciting times, Symfony 4 is just round the corner – coming out on November 30th – so this blog post might be irrelevant soon!

Is the refactor a good one? If not, what would be a better way?

One of the best framework practices is using param converters to directly invoke an entity from user request.

Example from Symfony documentation:

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;

/**
 * @Route("/blog/{id}")
 * @ParamConverter("post", class="SensioBlogBundle:Post")
 */
public function showAction(Post $post)
{

}

More on param converters:

http://symfony.com/doc/current/bundles/SensioFrameworkExtraBundle/annotations/converters.html

Organizing Your Business Logic (Symfony 4.2 Best Practices), Organizing Your Business Logic: In computer software, business logic or in Symfony, you should execute the following command to install the Doctrine fixtures  Questions: Any ideas / feedback are welcome 🙂 I run into a problem in how to handle business logic around my Doctrine2 entities in a big Symfony2 application. (Sorry for the post length) After reading many blogs, cookbook and others ressources, I find that : Entities might be used only for data mapping persistence (“anemic

Robert C. Martin (the clean code guy) says in his new book clean architecture, that you should put your business logic independently from your framerwork, because the framework will change with time.

So you can put your business logic in a seperate folder like App/Core or App/Manager and avoid inheretence from symfony classes here:

<?php

namespace App\Core;


class UserManager extends BaseManager implements ManagerInterface
{

}

Business logic in MVC, But there's no technical reason for putting business logic inside of a bundle. If you like, you can create your own namespace inside the src/ directory and put  The Symfony Framework Best Practices¶ This article describes the best practices for developing web applications with Symfony that fit the philosophy envisioned by the original Symfony creators. If you don't agree with some of these recommendations, they might be a good starting point that you can then extend and fit to your specific needs. You

What is meant by business logic in an application server?, Symfony2: Organizing your Business Logic into Models¶ From Audrius As Symfony is In other words, the goal is to put your logic in services. Balance that with  Now you have to define a service (that is a PHP class with a "lazy" instance) for all business logic; this is the place to put "heavy" code. Once you've recorded the service into your application, you can use it almost everywhere and that involves code reuse and so on. When you render and post a form,

What is business logic?, Business logic (also known as the domain logic) is all about the way business wants to handle the data. With this definition, it seems that the Model layer in a  Step 4 − HttpKernel is the core component of the Symfony web framework. HttpKernel resolves the controller of the given request using Routing component and forward the request to the target controller. Step 5 − All the business logic takes place in the target controller. Step 6 − The controller will interact with Model,

Organizing Your Business Logic (Symfony 2.5 Best Practices), Symfony 4 logo. One of my This can easily happen while mixing structure and business logic. This way I centralize all the data verifications in one place. DateTimeType Field¶. This field type allows the user to modify data that represents a specific date and time (e.g. 1984-06-05 12:15:30). Can be rendered as a text input or select tags.

Symfony2: Organizing your Business Logic into Models > Question , I want to talk about namespacing services in Symfony, specifically Symfony3. These are exciting times, Symfony 4 is just round the corner  Symfony versus Flat PHP¶. Why is Symfony better than just opening up a file and writing flat PHP? If you've never used a PHP framework, aren't familiar with the Model-View-Controller (MVC) philosophy, or just wonder what all the hype is around Symfony, this article is for you.

Comments
  • What is the purpose of $modified and what is the purpose of the second parameter to getUserById()?
  • Well , the domain business logic goes into model layer. Mosley in the domain objects.
  • @redbirdo : it doesn't matter for the purpose of question.
  • @tereško : so I'm "walking a good road". I've read your answer and I've found that some points fits perfectly with my description above (entities: domain objects and validators, services: act onto that domain objects and Data Mappers (i.e. repository and entity manager))
  • @DonCallisto I think the second parameter to getUserById() does matter as I was trying to understand whether your UserManager has a well-defined interface (in the context of 'Is the refactor a good one'). At least I would suggest that you avoid exposing the $request object to your UserManager as it's a UI construct. It would be better to extract the id from the $request and pass it to the UserManager.
  • Thank you for answer to my question. I've read those articles but that give me nothing more that what i've suppose to know :) If you can expand your answer with more details and fit it with my "real" example, I'll be happy (as all the comunity will be) to read, understand and - even - give you a positive feedback.
  • Yes I know, this is a very old answer and, btw, your should be a comment: you're not answering to my question. However now I know where to place business logic: where it belong. I mean, if logic is related to an entity, is almost mandatory (at least to me) to keep it INSIDE entity; otherwise I now use a service for it that could split the logic into sub-services in order to keep single principle responsability valid. Cheers!
  • the logic should never be placed inside an entity
  • Yes, that's true, I've read that book years ago and since then my ideas are more accurate about this topic :)
  • Yes, I know how it works: been here since 5/7 years :) This answer btw seems to be too "generic" to be upvoted
  • this is very symfony specific, this is how I implement my business logic into the framework