Symfony framework comes with a built-in console tool that we can trigger by simply executing the following command within our project root directory:
php bin/console
By doing so, an extensive list of available commands is shown on screen, sectioned into the following groups:
assetscacheconfigdebugdoctrinegeneratelintormroutersecurityserverswiftmailertranslationThese empower us with various functionalities. Our special interest moving forward is going to be around doctrine and generate commands. The doctrine command, more specifically doctrine:generate:crud, generates a CRUD based on an existing Doctrine entity. Furthermore, the doctrine:generate:entity command generates a new Doctrine entity inside an existing bundle. These can be extremely handy for cases where we want a quick and easy entity creation, alongside the entire CRUD around it. Similarly, generate:doctrine:entity and generate:doctrine:crud do the same thing.
Before we go ahead and test these commands, we need to make sure we have our database configuration parameters in place so that Symfony can see and talk to our database. To do so, we need to set appropriate values in app/config/parameters.yml file.
For the purpose of this section, let's go ahead and create a simple Customer entity within the default AppBundle bundle, with entire CRUD around it, assuming the following properties on Customer entity: firstname, lastname, and e-mail. We start by running the php bin/console generate:doctrine:entity command from within the project root directory, which results in the following output:

Here we first provided AppBundle:Customer as entity name and confirmed the use of annotations as configuration format.
Finally, we are asked to start adding the fields to our entity. Typing in the first name and hitting enter moves us through a series of short questions about our field type, length, nullable, and unique states, as shown in the following screenshot:

We should now have two classes generated for our Customer entity. Via the help of Symfony and Doctrine, these classes are put in context of Object Relational Mapper (ORM), as they link the Customer entity with the proper database table. However, we haven't yet instructed Symfony to actually create the table for our entity. To do so, we execute the following command:
php bin/console doctrine:schema:update --force
This should produce the output as shown in the following screenshot:

If we now take a look at the database, we should see a customer table with all the proper columns created with SQL create dsyntax as follows:
CREATE TABLE `customer` ( `id` int(11) NOT NULL AUTO_INCREMENT, `firstname` varchar(255) COLLATE utf8_unicode_ci NOT NULL, `lastname` varchar(255) COLLATE utf8_unicode_ci NOT NULL, `email` varchar(255) COLLATE utf8_unicode_ci NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `UNIQ_81398E09E7927C74` (`email`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
At this point, we still do not have an actual CRUD functionality in place. We simply have an ORM empowered Customer entity class and appropriate database table behind it. The following command will generate the actual CRUD controllers and templates for us:
php bin/console generate:doctrine:crud
This should produce the following interactive output:

By providing the fully classified entity name AppBundle:Customer, generator proceeds with a series of additional inputs, from generating write actions, type of configuration to read, to prefix of route, as shown in the following screenshot:

Once done, we should be able to access our Customer CRUD actions by simply opening a URL like http://test.app/customer/ (assuming test.app is the host we set for our example) as shown:

If we click on the Create a new entry link, we will be redirected to the /customer/new/ URL, as shown in the following screenshot:

Here we can enter the actual values for our Customer entity and click Create button in order to persist it into the database customer table. After adding a few entities, the initial /customer/ URL is now able to list them all, as shown in the following screenshot:

Here we see links to show and edit actions. The show action is what we might consider the customer facing action, whereas the edit action is the administrator facing action. Clicking on the edit action, takes us to the URL of the form /customer/1/edit/, whereas number 1 in this case is the ID of customer entity in database:

Here we can change the property values and click Edit to persist them back into the database, or we can click on the Delete button to remove the entity from the database.
If we were to create a new entity with an already existing e-mail, which is flagged as a unique field, the system would throw a generic error as such the following one:

This is merely default system behavior, and as we progress further we will look into making this more user friendly. By now, we have seen how powerful Symfony's console is. With a few simple commands, we were able to create our entity and its entire CRUD actions. There is plenty more the console is capable of. We can even create our own console commands as we can implement any type of logic. However, for the purpose of our needs, current implementation will suffice for a moment.