8000 Updated the Best Practices for Symfony 4 and Flex · symfony/symfony-docs@b997c1e · GitHub
[go: up one dir, main page]

Skip to content

Commit b997c1e

Browse files
committed
Updated the Best Practices for Symfony 4 and Flex
1 parent 724e5c4 commit b997c1e

File tree

9 files changed

+129
-370
lines changed

9 files changed

+129
-370
lines changed

best_practices/business-logic.rst

Lines changed: 7 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@ The blog application needs a utility that can transform a post title (e.g.
3232
"Hello World") into a slug (e.g. "hello-world"). The slug will be used as
3333
part of the post URL.
3434

35-
Let's create a new ``Slugger`` class inside ``src/Utils/`` and
36-
add the following ``slugify()`` method:
35+
Let's create a new ``Slugger`` class inside ``src/Utils/`` and add the following
36+
``slugify()`` method:
3737

3838
.. code-block:: php
3939
@@ -50,22 +50,9 @@ add the following ``slugify()`` method:
5050
}
5151
}
5252
53-
Next, define a new service for that class.
54-
55-
.. code-block:: yaml
56-
57-
# config/services.yaml
58-
services:
59-
# ...
60-
61-
# use the fully-qualified class name as the service id
62-
App\Utils\Slugger:
63-
public: false
64-
65-
.. note::
66-
67-
If you're using the :ref:`default services.yml configuration <service-container-services-load-example>`,
68-
the class is auto-registered as a service.
53+
If you're using the :ref:`default services.yaml configuration <service-container-services-load-example>`,
54+
this class is auto-registered as a service whose ID is ``App\Utils\Slugger`` (or
55+
simply ``Slugger::class`` if the class is already imported in your code).
6956

7057
Traditionally, the naming convention for a service was a short, but unique
7158
snake case key - e.g. ``app.utils.slugger``. But for most services, you should now
@@ -77,8 +64,8 @@ use the class name.
7764
except when you have multiple services configured for the same class (in that
7865
case, use a snake case id).
7966

80-
Now you can use the custom slugger in any controller class, such as the
81-
``AdminController``:
67+
Now you can use the custom slugger in any other service or controller class,
68+
such as the ``AdminController``:
8269

8370
.. code-block:: php
8471
@@ -127,36 +114,6 @@ personal taste.
127114
We recommend YAML because it's friendly to newcomers and concise. You can
128115
of course use whatever format you like.
129116

130-
Service: No Class Parameter
131-
---------------------------
132-
133-
You may have noticed that the previous service definition doesn't configure
134-
the class namespace as a parameter:
135-
136-
.. code-block:: yaml
137-
138-
# config/services.yaml
139-
140-
# service definition with class namespace as parameter
141-
parameters:
142-
slugger.class: App\Utils\Slugger
143-
144-
services:
145-
app.slugger:
146-
class: '%slugger.class%'
147-
148-
This practice is cumbersome and completely unnecessary for your own services.
149-
150-
.. best-practice::
151-
152-
Don't define parameters for the classes of your services.
153-
154-
This practice was wrongly adopted from third-party bundles. When Symfony
155-
introduced its service container, some developers used this technique to easily
156-
allow overriding services. However, overriding a service by just changing its
157-
class name is a very rare use case because, frequently, the new service has
158-
different constructor arguments.
159-
160117
Using a Persistence Layer
161118
-------------------------
162119

best_practices/creating-the-project.rst

Lines changed: 27 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -4,53 +4,36 @@ Creating the Project
44
Installing Symfony
55
------------------
66

7-
In the past, Symfony projects were created with `Composer`_, the dependency manager
8-
for PHP applications. However, the current recommendation is to use the **Symfony
9-
Installer**, which has to be installed before creating your first project.
10-
117
.. best-practice::
128

13-
Use the Symfony Installer to create new Symfony-based projects.
9+
Use the `Symfony Skeleton`_ and `Composer`_ to create new Symfony-based projects.
1410

15-
Read the :doc:`/setup` article learn how to install and use the Symfony
16-
Installer.
11+
The **Symfony Skeleton** is a minimal and empty Symfony project which you can
12+
base your new projects on. Unlike past Symfony versions, this skeleton installs
13+
the absolute bare minimum amount of dependencies to make a fully working Symfony
14+
project. Read the :doc:`/setup` article to learn more about installing Symfony.
1715

1816
.. _linux-and-mac-os-x-systems:
1917
.. _windows-systems:
2018

2119
Creating the Blog Application
2220
-----------------------------
2321

24-
Now that everything is correctly set up, you can create a new project based on
25-
Symfony. In your command console, browse to a directory where you have permission
26-
to create files and execute the following commands:
22+
In your command console, browse to a directory where you have permission to
23+
create files and execute the following commands:
2724

2825
.. code-block:: terminal
2926
3027
$ cd projects/
31-
$ symfony new blog
32-
33-
# Windows
34-
c:\> cd projects/
35-
c:\projects\> php symfony new blog
36-
37-
.. note::
38-
39-
If the installer doesn't work for you or doesn't output anything, make sure
40-
that the `Phar extension`_ is installed and enabled on your computer.
28+
$ composer create-project symfony/skeleton blog
4129
4230
This command creates a new directory called ``blog`` that contains a fresh new
43-
project based on the most recent stable Symfony version available. In addition,
44-
the installer checks if your system meets the technical requirements to execute
45-
Symfony applications. If not, you'll see the list of changes needed to meet those
46-
requirements.
31+
project based on the most recent stable Symfony version available.
4732

4833
.. tip::
4934

50-
Symfony releases are digitally signed for security reasons. If you want to
51-
verify the integrity of your Symfony installation, take a look at the
52-
`public checksums repository`_ and follow `these steps`_ to verify the
53-
signatures.
35+
The technical requirements to run Symfony are simple. If you want to check
36+
if your system meets those requirements, read :doc:`/reference/requirements`.
5437

5538
Structuring the Application
5639
---------------------------
@@ -61,47 +44,29 @@ number of files and directories generated automatically:
6144
.. code-block:: text
6245
6346
blog/
64-
├─ app/
65-
│ ├─ config/
66-
│ └─ Resources/
67-
├─ bin
47+
├─ bin/
6848
│ └─ console
49+
├─ config/
50+
└─ public/
51+
│ └─ index.php
6952
├─ src/
70-
│ └─ AppBundle/
53+
│ └─ Kernel.php
7154
├─ var/
7255
│ ├─ cache/
73-
│ ├─ logs/
74-
│ └─ sessions/
75-
├─ tests/
76-
│ └─ AppBundle/
77-
├─ vendor/
78-
└─ web/
56+
│ └─ log/
57+
└─ vendor/
7958
8059
This file and directory hierarchy is the convention proposed by Symfony to
81-
structure your applications. The recommended purpose of each directory is the
82-
following:
83-
84-
* ``app/config/``, stores all the configuration defined for any environment;
85-
* ``app/Resources/``, stores all the templates and the translation files for the
86-
application;
87-
* ``src/AppBundle/``, stores the Symfony specific code (controllers and routes),
88-
your domain code (e.g. Doctrine classes) and all your business logic;
89-
* ``var/cache/``, stores all the cache files generated by the application;
90-
* ``var/log/``, stores all the log files generated by the application;
91-
* ``var/sessions/``, stores all the session files generated by the application;
92-
* ``tests/AppBundle/``, stores the automatic tests (e.g. Unit tests) of the
93-
application.
94-
* ``vendor/``, this is the directory where Composer installs the application's
95-
dependencies and you should never modify any of its contents;
96-
* ``web/``, stores all the front controller files and all the web assets, such
97-
as stylesheets, JavaScript files and images.
60+
structure your applications. It's recommended to keep this structure because it's
61+
easy to navigate and most directory names are self-explanatory, but you can
62+
:doc:`override the location of any Symfony directory </configuration/override_dir_structure>`:
9863

9964
Application Bundles
10065
~~~~~~~~~~~~~~~~~~~
10166

10267
When Symfony 2.0 was released, most developers naturally adopted the symfony
10368
1.x way of dividing applications into logical modules. That's why many Symfony
104-
apps use bundles to divide their code into logical features: UserBundle,
69+
apps used bundles to divide their code into logical features: UserBundle,
10570
ProductBundle, InvoiceBundle, etc.
10671

10772
But a bundle is *meant* to be something that can be reused as a stand-alone
@@ -111,64 +76,11 @@ ProductBundle, then there's no advantage to having two separate bundles.
11176

11277
.. best-practice::
11378

114-
Create only one bundle called AppBundle for your application logic.
115-
116-
Implementing a single AppBundle bundle in your projects will make your code
117-
more concise and easier to understand.
118-
119-
.. note::
120-
121-
There is no need to prefix the AppBundle with your own vendor (e.g.
122-
AcmeAppBundle), because this application bundle is never going to be
123-
shared.
124-
125-
.. note::
126-
127-
Another reason to create a new bundle is when you're overriding something
128-
in a vendor's bundle (e.g. a controller). See :doc:`/bundles/inheritance`.
129-
130-
All in all, this is the typical directory structure of a Symfony application
131-
that follows these best practices:
132-
133-
.. code-block:: text
134-
135-
blog/
136-
├─ app/
137-
│ ├─ config/
138-
│ └─ Resources/
139-
├─ bin/
140-
│ └─ console
141-
├─ src/
142-
│ └─ AppBundle/
143-
├─ tests/
144-
│ └─ AppBundle/
145-
├─ var/
146-
│ ├─ cache/
147-
│ ├─ logs/
148-
└─ sessions/
149-
├─ vendor/
150-
└─ web/
151-
├─ app.php
152-
└─ app_dev.php
153-
154-
.. tip::
155-
156-
If your Symfony installation doesn't come with a pre-generated AppBundle,
157-
you can generate it by hand executing this command:
158-
159-
.. code-block:: terminal
160-
161-
$ php bin/console generate:bundle --namespace=AppBundle --dir=src --format=annotation --no-interaction
162-
163-
Extending the Directory Structure
164-
---------------------------------
79+
Don't create any bundle to organize your application logic.
16580

166-
If your project or infrastructure requires some changes to the default directory
167-
structure of Symfony, you can
168-
:doc:`override the location of the main directories </configuration/override_dir_structure>`:
169-
``cache/``, ``logs/`` and ``web/``.
81+
Symfony applications can still use third-party bundles (installed in ``vendor/``)
82+
to add features, but you should use PHP namespaces instead of bundles to organize
83+
your own code.
17084

85+
.. _`Symfony Skeleton`: https://github.com/symfony/skeleton
17186
.. _`Composer`: https://getcomposer.org/
172-
.. _`Phar extension`: http://php.net/manual/en/intro.phar.php
173-
.. _`public checksums repository`: https://github.com/sensiolabs/checksums
174-
.. _`these steps`: http://fabien.potencier.org/signing-project-releases.html

best_practices/forms.rst

Lines changed: 13 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ Building Forms
1212

1313
Define your forms as PHP classes.
1414

15-
The Form component allows you to build forms right inside your controller
16-
code. This is perfectly fine if you don't need to reuse the form somewhere else.
17-
But for organization and reuse, we recommend that you define each
18-
form in its own PHP class::
15+
The Form component allows you to build forms right inside your controller code.
16+
This is perfectly fine if you don't need to reuse the form somewhere else. But
17+
for organization and reuse, we recommend that you define each form in its own
18+
PHP class::
1919

2020
namespace App\Form;
2121

@@ -67,14 +67,6 @@ To use the class, use ``createForm()`` and pass the fully qualified class name::
6767
// ...
6868
}
6969

70-
Registering Forms as Services
71-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
72-
73-
You can also :ref:`register your form type as a service <form-field-service>`.
74-
This is only needed if your form type requires some dependencies to be injected
75-
by the container, otherwise it is unnecessary overhead and therefore *not*
76-
recommended to do this for all form type classes.
77-
7870
Form Button Configuration
7971
-------------------------
8072

@@ -98,7 +90,7 @@ scope of that form:
9890
{
9991
$builder
10092
// ...
101-
->add('save', SubmitType::class, array('label' => 'Create Post'))
93+
->add('save', SubmitType::class, ['label' => 'Create Post'])
10294
;
10395
}
10496
@@ -127,7 +119,7 @@ some developers configure form buttons in the controller::
127119
$form = $this->createForm(PostType::class, $post);
128120
$form->add('submit', SubmitType::class, array(
129121
'label' => 'Create',
130-
'attr' => array('class' => 'btn btn-default pull-right'),
122+
'attr' => ['class' => 'btn btn-default pull-right'],
131123
));
132124

133125
// ...
@@ -144,8 +136,7 @@ view layer:
144136
{{ form_start(form) }}
145137
{{ form_widget(form) }}
146138

147-
<input type="submit" value="Create"
148-
class="btn btn-default pull-right" />
139+
<input type="submit" class="btn" value="Create" />
149140
{{ form_end(form) }}
150141

151142
Rendering the Form
@@ -161,7 +152,7 @@ all of the fields:
161152

162153
.. code-block:: html+twig
163154

164-
{{ form_start(form, {'attr': {'class': 'my-form-class'} }) }}
155+
{{ form_start(form, {attr: {class: 'my-form-class'} }) }}
165156
{{ form_widget(form) }}
166157
{{ form_end(form) }}
167158

@@ -197,13 +188,8 @@ Handling a form submit usually follows a similar template:
197188
// render the template
198189
}
199190
200-
There are really only two notable things here. First, we recommend that you
201-
use a single action for both rendering the form and handling the form submit.
202-
For example, you *could* have a ``newAction()`` that *only* renders the form
203-
and a ``createAction()`` that *only* processes the form submit. Both those
204-
actions will be almost identical. So it's much simpler to let ``newAction()``
205-
handle everything.
206-
207-
Second, is it required to call ``$form->isSubmitted()`` in the ``if`` statement
208-
before calling ``isValid()``. Calling ``isValid()`` with an unsubmitted form
209-
is deprecated since version 3.2 and will throw an exception in 4.0.
191+
We recommend that you use a single action for both rendering the form and
192+
handling the form submit. For example, you *could* have a ``newAction()`` that
193+
*only* renders the form and a ``createAction()`` that *only* processes the form
194+
submit. Both those actions will be almost identical. So it's much simpler to let
195+
``newAction()`` handle everything.

0 commit comments

Comments
 (0)
0