For the past year and a half, I've been using symfony 2 for developing web applications. During this time, I started a new project three times, in three projects I worked with the inherited code, and also conducted a review of about 15 test tasks for the framework.
It would probably be great to be able to come back a year and a half ago and give yourself some tips before starting your first project. Alas, it is impossible. But maybe my advice may be useful to other novice developers on symfony?
')
Observe code style and conventions by name.
I will not speak for the thousandth time for the thousandth time about the importance of code style, but most beginner developers do not observe it.
Fortunately, this problem is easy to fix. Modern IDEs can automatically format the code according to selected rules. Now I use PHPStorm. There are preset settings for symfony, automatic addition of the use statement, and many more goodies.
If we talk about coding standards, it is impossible not to mention the
PHP CS Fixer from Fabien Potencier. PHP CS Fixer will be a must-have tool for you after some time.
A small lyrical digression. In sociology, there is the Theory of Broken Windows, which suggests that ignoring generally accepted rules by some people provokes other people to ignore these and other rules as well. Correct code style errors in the project, do not leave “broken windows” in your code.
Don't make fat controllers
Thick stupid ugly controllers (TTUC), the second most popular error that occurs in the code of a novice developer. Much has been written about thick controllers. In a nutshell, the controllers are not reusable software modules in the general case. Therefore, you should not keep business logic here. The logic in the controllers violates the DRY principle and provokes copy-paste. Take business logic to the services layer, to the model, anywhere. Do not hesitate to create a new class, service, method, hesitate to make TTUCS.
Do not make container dependent services.
Best of all forget that this possibility exists at all. The moment you create a container-dependent service, you will no longer control what happens in it. And if you want to introduce the entire container into the service, just because it “swells” from dependencies, then most likely you have architecture problems. The container in the service will provoke you to violate the Single responsibility principle and in no way will contribute to the creation of the correct design. Container aware services will be hard to test. And if you make yourself a hierarchy based on this class, then it will also be hard to refactor.
Look at the Service Container from the other side. This is primarily a tool for configuring dependencies, and not a place from where you can pull any service. Do not use the container in classes other than controllers. Better yet, train yourself and the controllers to do services. It will also be easier for you to understand and control what happens in your code.
Write the code as simple as possible
First, stop making unnecessary interfaces. Do not enter the interface only in order not to make a dependency on a particular class. Your only concrete implementation of the interface will probably live in the project for years. Do not be afraid to make dependencies on a particular class. You can easily refactor the code and add the interface when you see the need for it.
Second, make the public API of classes as simple as possible. In other words, you should not make public methods for a class that you will not use right now.
Third, make methods and properties that are not public class API private by default. You can always change the scope if you need to override a method or property. But when another programmer reads your code, he will be one hundred percent sure that this method is not used anywhere else.
Fourth, you should not implement now what will be used tomorrow. Practice shows that this ghostly tomorrow may never come. Yes, you can never say exactly how the requirements for the project will change. So why complicate the project now? Why do you do extra work?
Well and, fifthly, do not include whole bundles in the project, for the sake of one little feature. For example, you don’t need a FOSRestBundle to return JSON in one of the controllers.
Do not abuse the comments
Do not comment on what is obvious. Do not add comments to the methods, just because your IDE can do this automatically. If you have successfully chosen the names of classes, methods, variables and properties, you should never want to add a comment to the code.
However, sometimes comments are simply necessary. Do not forget to comment on the code when the logic is complex or not obvious. Add comments only to key methods, i.e. to those who do the most important work. Always cover with comments and tests methods that use complex regulars.
Understand how Doctrine works
Most often, your own errors, not ORM, will cause the application to work slowly with the database. Correctly determine the type and direction of relationships between entities. Do not abuse inheritance in entities. Constantly look into the profiler to control how fast the data access layer works and what requests the ORM creates. Avoid nested transactions. Call flush only in controller. Read the Doctrine documentation again, at least diagonally.
Use all the features of Twig
Twig is a very good template engine. In time, you will understand this. It is very easy to expand if necessary. But the fact that there is a standard delivery with a head is enough to stop duplicating the code in the templates. Re-read the documentation again, there is little. And use all the features of this tool.
Use exceptions wisely
Always define a custom type for exceptions that may occur in production. Write clear messages for exceptions that may arise in the design. Handle critical exceptions in one place, and do not try to catch them in each controller. Catch the exceptions that can be fixed as close as possible to the place in which they are thrown.
Do not make configs bulky
Symfony gives you all the tools to organize your configuration files exactly as you need. Large configs are uncomfortable. They should be broken down into smaller ones so that any developer in the project can easily navigate to where the configuration is.
Update dependencies often in the project
Use stable versions of bundles if you can. And if not, update the dependencies as often as possible. Errors are best corrected as they occur. When you collect a lot of updates, it will be much more difficult to eliminate all incompatibility problems.
Write tests
Write acceptance tests on Behat from the first day of the project. Then it will be harder to cover all the functionality. Creating a test environment takes time. But in the initial stages, this time will be spread between other tasks. And in the future, these tests will often help you out.
Write unit tests for PHPUnit. At least on the most complex and most important methods. Write the tests before the code, it will allow you to create a better design. Profit from unit tests will be in the absence of bugs and regressions in the code.
Well, the most important advice I would like to give myself: “Do not be afraid to make mistakes, but strive to work in a team with more experienced developers who will point them to you. Well, if you do not have such an opportunity in a commercial project right now, look for such people in OSS. ”
A few links: