Basic cruds with Symfony
This tutorial is a follow up to the previous one about the Symfony framework. We’ll start to have some hands-on real work to see the Symfony cruds operation. Still, we need to know about ORMs, MVC and Twig before actually starting.
Why the Object Relational Mapping ?
Object-relational mapping is a programming technique used to persist data objects to a relational database and retrieve them. It relies heavily on metadata about both the database and objects, so that the objects know nothing about the database and the database knows nothing about how the data is structured in the application. We’ll concretely check this out in the next section.
ORM performs the task of managing the application’s interactions with the database. Once you’ve used an ORM’s tools to create mappings and objects for use in an application, those objects completely manage the application’s data access needs. You won’t have to write any other low-level data access code. From this we can conclude the first why for the use of an ORM: application’s design. An ORM provides a clean separation of concerns in a well-designed data application. We can also tell that developers will get rid of writing down the data access code, which obviously helps with productivity. Though the amount of code is unlikely to be reduced, the ORM tool generates all the data access code automatically based on the data model you define. The code generated by the ORM is presumably well-tested, so you usually don’t need to worry about testing it extensively. Here comes another why for using an ORM: application’s maintainability. Over the long term, you can refactor the database schema or the model definition without affecting how the application uses the data objects.
There are abviously different ORMs to use. In the case of a Symfony project, the framework provides tight integration with a third-party library called Doctrine.
In the next section, you’ll learn how to start leveraging the Doctrine ORM in your Symfony projects to give you rich database interactions.
The MVC pattern, bundles and Twig
Before starting our tutorial we need to set few more notions clear.
Symfony relies on the MVC pattern, which consists of three levels :
• The Model represents the information on which the application operates, its business logic.
• The View renders the model into a web page suitable for interaction with the user.
• The Controller responds to user actions and invokes changes on the model or view as appropriate.
The MVC architecture separates the business logic (model) and the presentation (view), resulting in greater maintainability and has different advantages which we can filter in another post. For instance, you have to keep in mind that we’ll be working through three different “levels” or layers.
In order to seperate the program logic from presentation we need a template engine. For symfony projects, Twig, a template engine for PHP, is used. It has a very concise syntax which makes HTML templates more readable through php code, and it’s fast and secure. We’ll have hands on this through the tutorial.
One last thing you need to consider before jumping into your first Symfony sample project, is Bundles. Bundles in symfony are a set of files within a directory that implement a single feature. I refer to them as “modules”. Every “module” containes everything related to it’s features including PHP files, templates, stylesheets, JavaScript files, and tests. Taking the example of an e-commerce app, you can create a bundle for products, a bundle for payment and a bundle for user management. Bundles names must follows some specifications: starts with a vendor segment, followed by zero or more category segments, and it ends with the namespace short name, which must end with a Bundle suffix.
In the next section, we’ll put all of these theories together.
Symfony Cruds
Obviously you would need to create a new symfony project ( you can follow the instructions on my previous Symfony post ). We’ll use the console commands to automatically generate our data models and the associated crud operations. Still, you can manually define those, specially if you want to get used to the parameters and metadada within the Doctrine entities. And still, I’ll explain each bit of code generated.
1- Create a project bundle
Open your command prompt and navigate to your project’s directory. Use the following command to create a new bundle:
$ php bin/console generate:bundle –namespace=myApp/LibraryBundle
If you’re using the Netbeans IDE, you can run the console commands by right-clicking your project and going to Symfony>Run command. Then choose generate:bandle and complete the required data as follows:
Bundle name : myAppLibraryBundle
Configuration format: yml
Turning back to the previous section where we defined what twig is and presented the MVC pattern and it’s three layers, if you check out the content of your generated bundle you would find a Controller folder, a Views folder under resources that contains a twig file, and some configuration files. You would now need to add the models.
2- Generate Doctrine entities
To generate entities you can use the following command:
$ php bin/console doctrine:generate:entity
You can use Netbeans as mentionned above. You’ll find the doctrine:generate:entities command.
First, you need to give the entity a name. You must use the shortcut notation like AcmeBlogBundle:Post . You can add some fields or just generate a blank entity.
3- Map your entities to a database
To map an exising doctrine entity into a database column, you first need to
– create a new database through phpmyadmin
– change database_name in app/config/parameters.yml to your new base’s name:
– execute the schema:update command to map your data object to a new column in that database:
$ php bin/console doctrine:schema:update – – force
4- Generate your cruds
To automatically generate crud methods execute the following command:
$ php bin/console generate:doctrine:crud
With the Entity shortcut name: CustomBookBundle:Book and the Routes prefix: /book
Finally, you can test this out through your browser by navigating to http://localhost/crudsTest/web/app_dev.php/book/ :
How things worked ?
As we said we’re working through three different layers: the views, the models and their controllers. When we first executed the generate:bundle command we created a myAppLibraryBundle folder having a structure with Controller and Resources/Views folders. Then we added the Entity folder with generate:entity command.
Entities are our data models, they simply hold a set of fields with their getters and setters. Doctrine entities have metadata attributes or annotations, a configuration that tells Doctrine how your entity should be stored in the database. Taking the example our Book class, with no additional information, Doctrine expects the entity to be saved into a table with the same name. You can change this by configuring information about the table:
<?php /** * @Entity * @Table(name="books") */ class Book { //... }
Then fields are mapped to columns in a table, that’s why you’ll find annotations on each field of your entities. These annotations define different parameters of the column such as it’s type, wether it’s an automatically generated or a unique value or not..ect.
<?php /** @Entity */ class Book { /** @Column(type="integer") */ private $id; /** @Column(length=30) */ private $title; }
Moving to the views. Under app/Resources/views you’ll find a book folder containing all twig files generated. Taking the example of index.html.twig, this is the HTML file corresponding to the ui you see when you first test your code (screenshot above). Like every twig file, it contains variables or expressions, which get replaced with values when the file is evaluated by the controller. We have the books variable in here. We’ll see how it’s gonna be replaced by a value in the controller.
Controllers invoke changes on the view or the model depending on user interactions as we’ve previously explained. So what we’ll find in the generated BookController class is a set of functions (crud functions in our case) that make change in either the database or the ui (here comes the role of Twig as we explained it). Taking the first function indexAction :
public function indexAction() { $em = $this->getDoctrine()->getManager(); $books = $em->getRepository('myAppLibrairieBundle:Book')->findAll(); return $this->render('book/index.html.twig', array( 'books' => $books, )); }
it retrieves all books from database and stores them in $books variables, then loads the book/index.html.twig file giving the value of &books to the books variable in the twig file.
Overall, that’s how things work. Data objects with mapping annotations to map them into database tables with the appropriate columns, twig files defining the ui with variables that get their values when the controller evaluates the file, and php classes controlling or syncing twigs and database depending on user actions “using actions” or functions to do the work.
Still there are alot of other notions and details to get, about repositiories and data retieval, forms and HTML templates (unless you want to keep your ui like the one we got here!). We’ll go through them in the following tutorials.
Happy coding ! ( is it coding what we did ? better say Happy learning !).
Recent Comments