Symfony. Where should I place complex queries? - php

I have a question. I'm working on symfony based web application. I faced with one issue. Where should I place complex queries with many joins? Should I create method in the repository class? Or it should be placed in the service layer?

Repository class is a good way to go. I do not know what you mean by "service layer". You can define repository as a service, so it can be injected in controllers, commands or anything else. That will make your queries reusable in the whole project.

It is highly architecture-specific.
Symfony is a framework, it does not require to be used with specific architecture pattern like Service layer, MVC, etc.
If you use Service layer with combination of Repository pattern,
the business logic should be in your service, and complex queries could be in your repositories

Related

Does Symfony have an interface for ORMs?

I wonder if there is an interface that diverse ORM should implement for Symfony or not.
The question came up when I was building a service that accepts an ORM (Doctrine right now), and wanted to declare type.
I guess different ORM have different behaviour and classes... in those cases, how can build entities that do not depend on specific ORM in case one wants to switch later?
Generally, Symfony is agnostic in regard to your choice of ORM.
The standard edition comes bundled with Doctrine and also contains some “bridge” code to ease the integration.
However, you can use any ORM you’d like to. For example, Propel is known to work well with Symfony, too. The Propel team also maintains an integration bundle.
There is no “interface” in the sense of a formal description an ORM has to comply with. There is no such thing as interface SymfonyOrmInterface {}.
Think about it, how and why should Symfony demand this? Symfony is a HTTP framework built on a set of loosely coupled components. Most of these components don’t even know what an ORM is or if one is currently available in the application.
You will usually install your ORM through composer, and it will be available in your business code (assuming that it supports autoloading with PSR-0/-4).
Of course, for a proper integration of an ORM into Symfony, there are some conventions and features, such as:
CLI commands, e.g. for schema updates,
Managing configuration values through the global config.yml and parameters.yml files,
Providing services and dependencies through Dependency Injection.
These are implemented in integration bundles, usually provided by the respective ORM vendor.
For your business code, this means that you can’t just replace one ORM with another one. There are significant differences accross ORMs in regard to storage abstraction, caching, querying, hydration, etc. Replacing an ORM will always require you to adapt your business logic to some exent, and not only in a Symfony project.

What is the advantage of using a service in symfony

I have a question, why symfony use a service instead of "use" directly into a controller.
I have a class named DisplayManager and I declare this class as a service.
Why not use DisplayManager directly into a controller using "use DisplayManager"
Thanks
The advantage of thinking about "services" is that you begin to think about separating each piece of functionality in your application into a series of services. Since each service does just one job, you can easily access each service and use its functionality wherever you need it. Each service can also be more easily tested and configured since it's separated from the other functionality in your application. This idea is called service-oriented architecture and is not unique to Symfony or even PHP. Structuring your application around a set of independent service classes is a well-known and trusted object-oriented best-practice. These skills are key to being a good developer in almost any language.
http://symfony.com/doc/current/service_container.html
Questions that suggest define your class as service:
My class is used in several places in my application?
My class has many dependencies?
There is a good example for these topics here:
http://symfony.com/doc/current/service_container.html#what-is-a-service-container
Performance Advantage:
The service has a default condition that allows to the related class instantiate it only once.
Imagine a class with 5 dependencies (and these as well with their dependencies) and has been used in 20 parts of our system, what if we do not define this class as a service?
However define your class as a service is not required, this will always depend on the architecture of your system and the mission to be fulfilled its class, in addition to the dependencies you have.
Controllers are made only to take requests (http) and produce a response (http). No more. Never.
Services are totally independent classes that you can use everywhere. Moreover, with services, you can take advantage of DependencyInjection.
Services are more testable.
Services (like controllers and whatever) must have only a responsibility.
And so on ...

Global logging service

I have written my own logging class that I defined as a service and placed inside the AppBundle\Services namespace. I can access it easily inside the controller when I want to log something, but what about accessing it from other services?
I'd have to pass the logging service as a dependency injection, but what if I have more than 100 services defined (services, modules, event listeners etc. etc.), each of them having their own dependencies? It would create a mess.
I've been also thinking about extending some core service that defines the logging service, but then again - all my services, modules, event listeners, would have to extend one core class.
What's the best approach to solve this?
May be a good approach would be to rethink responsibilities in order to avoid the creation of too many services.
About the fact of consumming service itself, I think there are no problem to reuse as much as you need along the application lifecycle. In fact, symfony will handle the instantiation and you will be only consumming it as a service.
Another approach will be to create base classes for all your core objects, let these base classes to handle log services and final classes will log in a implicit way. This will not save service calls but almost will leave you to handle it manually.
If you think you will use your log feature in several projects then I recommend you to move to vendors folder and use it as external module, synchronised via composer to your github account. It will be like your own 3rd party product.
If you are not a symfony friend then you can break the law and create your own singleton pattern available by autoloading, but I think you should take advantage of the powerfull symfony service structure.

Security component from Symfony 2.0 as standalone

I'm trying to add Symfony 2.0 ACL to my frameworkless PHP application. Because of the lack of documentation on how to use Security component as standalone I've got totally confused and I've got stucked with questions: What class to include first? Which object to instance? Is it possible to be used without models and controllers?
Any suggestion on how to start or any good link?
Thanks
The SecurityServiceProvider for Silex might be a good place to start, as it integrates all of the essential component services in a single file. Although large, you'll probably find it much easier to digest than Symfony2's SecurityBundle.
In the interest of maintaining your sanity, you should consider using a service container to organize all of these objects. In the aforementioned provider class, the Silex Application class is a Pimple instance, so you should be able to port it stand-alone Pimple with modest effort. I saw this because integrating a Pimple service container into your application should be less invasive than adopting the Silex framework.
Once you have the essential security component classes working, you should be able to following along with the ACL documentation and add additional services to your container as needed. At that point, the ACL-specific sections of the SecurityBundle might prove helpful, as you can focus in on the relevant bits. Keep in mind that there are multiple cookbook entries for ACL in the documentation.
What class to include first?
You will most likely need to include at least parts if not all of the security core, then which ever ACL implementation that you are wanting to use. You can look at the dependencies that are listed in the beginning of the ACL implementation and see what they extend. For instance, the ACL/DBAL has the following dependencies called in the header:
namespace Symfony\Component\Security\Acl\Dbal;
use Doctrine\DBAL\Driver\Connection;
use Doctrine\DBAL\Driver\Statement;
use Symfony\Component\Security\Acl\Model\AclInterface;
use Symfony\Component\Security\Acl\Domain\Acl;
use Symfony\Component\Security\Acl\Domain\Entry;
use Symfony\Component\Security\Acl\Domain\FieldEntry;
use Symfony\Component\Security\Acl\Domain\ObjectIdentity;
use Symfony\Component\Security\Acl\Domain\RoleSecurityIdentity;
use Symfony\Component\Security\Acl\Domain\UserSecurityIdentity;
use Symfony\Component\Security\Acl\Exception\AclNotFoundException;
use Symfony\Component\Security\Acl\Exception\NotAllAclsFoundException;
use Symfony\Component\Security\Acl\Model\AclCacheInterface;
use Symfony\Component\Security\Acl\Model\AclProviderInterface;
use Symfony\Component\Security\Acl\Model\ObjectIdentityInterface;
use Symfony\Component\Security\Acl\Model\PermissionGrantingStrategyInterface;
But you would probably need to check each of those listed for their dependencies, and load those as well.
I would back-track through the dependencies, and keep track of what needs what. Cull those classes out into a separate location so that you have only what you need, and use some error trapping to determine that you have it all.
Which object to instance?
Your ACL. If the dependencies are all determined, and loaded, then you should be able to instantiate the ACL class object.
Is it possible to be used without models and controllers?
To be honest, I am not sure that using ACL outside of S2 is possible without a WHOLE lot of work, but if you can get it instantiated with everything it needs, then you should be able to use the object without an MVC model.
Unfortunately, from what I understand of S2, it is a full stack framework, and meant to be an all or nothing kind of thing. but if I were going to try and make it work, this would be the way I would go about it.
If u want to understand how to use use symfony2 component and how to integrate that within your project then read Fabien Potencier blog 'create your own framework'
post that will definitely help u to understand core of framework from and how to bootstrap symfony2 component in your project
there is also good document for ACL on symfony website

Is MVC + Service Layer common in zend or PHP?

You've probably heard of the Fat Model/Thin Controller vs. Thin Model/Fat Controller distinction. I recently heard that you can have something in between where some of the logic from the model goes into a service layer. How common is this? and do you know of (or can think of) any real examples that illustrate it?
Martin Fowler describes the Service Layer pattern of his great book Patterns of Enterprise Application Architecture. If you care about questions like the one you asked, you should read this book.
One use that comes to my mind is managing database transactions. Some people try to encapsulate starting and committing transactions in their domain models. But then they get confused when domain models invoke other domain models that also try to start and commit db transactions. So which model really gets to decide if a transaction is committed or rolled back? And what do you do if a given model is used in different ways by different clients?
The Service Layer is a solution for this, because this is the layer in which you can start and commit work that involves multiple domain models.
As for how common this is, I don't think it's common at all. Most people using Zend Framework (or any other PHP or Ruby framework) have just barely moved from "Active Record solves everything" to the new shiny, "Data Mapper solves everything." It seems this community learns only one new pattern every five years. They won't get to Service Layer for a while.
Re comment from #ktutnik:
No, the Service Layer pattern is different from Repository pattern. Repository is about abstracting database access so you can use a database like a Collection. Service Layer is about encapsulating complex application operations.
Another way of thinking about them is their relationship to the Domain Model. The Repository is used between the Domain Model and the database. Whereas the Service Layer uses one or more Domain Models.
Service Layer ---> Domain Model(s) ---> Repository ---> DBAL
Service layer advocacy is relatively new and still subject to a variety of interpretations. I think it means having a layer that leverages multiple domain models which the controllers call (I may be simplifying it too much though). I recently developed a website making use of this and practical advantages I've encountered are:
Features as a service helps with scalability. If you have an image service that initially uses the local service to do it's work it becomes easier to have that service point to another server or some 3rd party without having to make sweeping updates
Flexibility. Half way through the project I decided to change a core piece of functionality and was able to do so painlessly; allowing me to quickly weigh the pros and cons of the update. This flexibility is useful when rapid prototyping and instills a certain confidence because if you need to revisit something it's not going to be a nightmare.
Extensibility. I have already identified services in my application what I can forsee opening to other developers or other widgets, mobile apps in the future. Doing so in theory is just a matter of adding authentication and authorization to the service (because the features are already in it's own layer and I don't have to spend time trying to decouple what I want to expose from the rest of the code base).
Services are easy to add and drop (maybe this belongs with one of the earlier points). I have services that a specific to a specific stage in the project (e.g. invite only stage) that I can drop once that phase is over.
I think it has practical advantages and a key to success in implementation is having a good way to manage the services in the application. I use symfony's dependency injection component
See ZFEngine it's cmf on ZF with service layer realisation

Categories