Does Symfony have an interface for ORMs? - php

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.

Related

Symfony: Organising multi-client application’s business logic

Problem:
I’m unsure how to set up multi client application for Symfony so that we would not violate Symfony's best practices and work against the framework.
I would like to have one main Core namespace which would contain all the base model classes. Right next to the core I would like to set up client specific namespaces which would be used, based on client regional setting. For example LocalUS for US market, LocalUK, for UK market etc.
The Local* namespaces should take first priority for including twig templates, and as a fallback use core common shared views (as I understand, this is solvable via twig namespaces). Same goes for controllers and models - these are probably solvable via extending the Core namespaced classes? Is this all solvable via routing and providing paths for these Local* controllers?
I was looking up on github to see if there are any project that have similar setup but I couldn’t find anything.
A little background:
We have an older legacy PHP Application which was built in-house from ground up using plain PHP. As the application has grown over time, it has become hard to maintain good code quality and standards. It’s also very time consuming to teach new developers our application logic, since the application basically follows no standard design patterns and just does it’s own thing. A lot of the underlying code which handles routes, controllers etc seems to work like “magic” that nobody really dares to touch.
It is because of that we would like to migrate our application to Symfony3 framework. I’ve read some articles about the overall process of migrating legacy applications to symfony, and managed to do it with silex pretty well. Silex, however is a bit too lightweight, I found that the assetic service provider had a lot of functionality missing (twig namespacing etc), and decided it would be best if we could move to a full stack symfony framework instead.
Look into Symfony bundles - they do exactly what you need. You create a "base" bundle, than extend it with other bundles. That's how FOSUserBundle works - it provides everything you need, than you extend it and overwrite it.

Symfony. Where should I place complex queries?

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

Symfony MVC best practice for controllers

In a Symfony/Doctrine/PHP-project, a client is complaining that we've broken software development best practices. The complaint is about improper layering of the source code, and the lack of unit tests.
This is a sub $50k-project.
I believe that the client has an expert from the Java world, perhaps Spring Framework, looking at the source code.
We've been using proper MVC, as we see it.
View-logic is handled entirely by TWIG.
Database is handled entirely by Doctrine.
We're using Symfony Security for access control ($this->get('security.context')->isGranted('ROLE_ADMIN') and $this->get('security.context')->getToken()->getUser().
Beware that Symfony has changed the model a bit, since we started this project - but remains backward compatible.
In the controller the customer is specifically saying that it's wrong for the controller to handle:
Access Control (via Symfony Security)
Database Queries (via Doctrine)
"Parsing and other logic" for sending back responses (return $this->render('some_template.html.twig');)
The question
The client is saying that best practices is for the controller to simply pass on requests to another layer further down in the system.
Further he's saying that user-admin is based on a "custom model" where all users and roles are stored in the database - which makes plugging in a different access control system difficult. Specifically because role names seems to be hard coded such as via commands such as ($this->get('security.context')->isGranted('ROLE_ADMIN').
So; is there a definitive best practice on this field? What belongs in the controller, and is Doctrine, Twig, Symfony Security "sufficiently" a separate layer "below the controller".
Should there be yet another layer between the controller and Doctrine for example?
Source: http://fabien.potencier.org/what-is-symfony2.html
First, what is Symfony2?
First, Symfony2 is a reusable set of standalone, decoupled, and cohesive PHP components that solve common web development problems.
Then, based on these components, Symfony2 is also a full-stack web framework.
Depending on your project and depending on your needs, you can either pick and choose some of the Symfony2 components and start your project with them, or you can use the full-stack framework and benefit from the tight integration it provides out of the box. And choosing between the two different approaches is really up to you.
Is Symfony2 an MVC framework?
Symfony2 is really about providing the tools for the Controller part, the View part, but not the Model part. It's up to you to create your model by hand or use any other tool, like an ORM. Of course, tight integration exists for the most well known ORMs like Doctrine2 and Propel; but they are optional dependencies. The Symfony2 core features do not and will never rely on any ORM.
Symfony2 is an HTTP framework; it is a Request/Response framework. That's the big deal. The fundamental principles of Symfony2 are centered around the HTTP specification.
Symfony about best practices: https://symfony.com/doc/current/best_practices.html
You should rly read this about controller best practices:
https://symfony.com/doc/current/best_practices.html#controllers
You can read this answer https://stackoverflow.com/a/21701890/2160958

Doctrine 2 Migrations Workflow

I am developing a web application using Zend Framework 2 and Doctrine 2. I'm new to Doctrine 2 in general and Migrations in particular. I was wondering if there are any recommended best practices in using this. Some specific things I'm looking for:
A recommended workflow from development to deployment?
Do you include pre-populating data in migrations?
How to handle reverting to a previous version if migration fails.
Many thanks!
Doctrine has own library for migrations, that includes also Symfony bundle.
For Zend there probably is some bundle as well (maybe seek on Github a bit more)
As for your specific questions:
Nothing special. Basic workflow is nicely described in Symfony bundle documentation. We use it in pretty same way even in a different framework.
Yes, so every developer has fully operational system. For tests we use data-fixtures with minimal required data only.
It's managed by this package itself.
The Doctrine ORM module for ZF2 (DoctrineORMModule) has built-in support for Doctrine ORM migrations. There's a very brief blurb in the documentation about how to configure it. You can then access the migration commands (generate, migrate, etc) through the CLI interface that module provides (vendor/bin/doctrine-module)
As for my personal workflow I generally put initialization or pre-population data - the stuff you initially seed a new installation with - into database fixtures (which Doctrine ORM also supports and there is a ZF2 module for).

Install an ORM into an custom PHP5 framework

What is the procedure to install an ORM component such as Doctrine into an existing custom PHP5 MVC framework?
What are the minimal requirement in terms of framework architecture and fonctionalities ?
What are the possible problems to face ?
Would it be problematic to have side by side tables generated by the ORM and some by "old fashioned " SQL request?
The ORM is simply an abstraction for your database interactions. The Doctrine ORM wraps PHPs PDO library and adds some useful abstractions. To implement Doctrine into your existing framework you'll need to download the code and put it into a directory in your project. If you're already using third party libraries, place it there. If not, create a vendors directory and drop doctrine in it. You can follow the Doctrine documentation for installation and configuration details.
Once you've implemented doctrine, your task will be to update existing database interactions. If all database interactions are already handled through models, you should be able to write an abstract or interface base class for your models. From there, models can be updated to implement Doctrine methods for interaction.
If you have SQL scattered around the app, you should probably decouple the database interactions and isolate them into models then follow the process described above.
There is nothing about using the ORM that will prevent existing database interactions from operating, but that is very messy and should be avoided if at all possible.

Categories