A Sample MVC App Build on Top of Symfony2 and Laravel4 Components (Part-2 Introspection of the Skeleton) June 22, 2014Posted by Tournas Dimitrios in PHP, sample-MVC.
Welcome back to the second part of the article series “A Sample MVC App Build on Top of Symfony2 and Laravel4 Components”. Every project start with a skeleton, it’s the application’s folder and file structure (a blueprint so to speak). Unfortunately, there are no standards in this regard. While some frameworks (Symfony , Zend-Framework, Laravel) utilizes a skeleton according their own philosophy other frameworks (in particular micro-frameworks) are giving the developer the freedom to structure a skeleton according their own needs. The key point here is that the structure of the skeleton must be planned in such a way that any developer that might get involved into the project will get familiar instantly.
A long time ago :), before PHP released its 5.3 version (at december 2010) we were forced to follow a particular folder structure. Certainly the following motif is familiar to you : class Zend_Application_Module_Autoloader extends Zend_Loader_Autoloader_Resource We had to follow a corresponding folder structure so that the autoloader could do its job, at some extent the same motif is also followed today but we are not forced to do so. PHP Namespaces, which were initially applied as a solution for bypassing naming conflicts between different libraries that could exist in the same project, had also impact how a skeleton could be structured. Due to Composer (a PHP dependency manager), we can now customize its autoloader in a much more flexible way.
- Cache : When a controller needs to generate the response object, it hands the work off to the templating engine (Twig in our case) . Twig allows us to separate the business logic (stuff like : db tasks, and other dynamically defined functionality) from presentation logic (HTML code). Twig comes with a long list of predefined tags and filters that help the developer designates the “where and how” the data should be rendered. The Controller is only responsible to generate the data (the “what” to render). The whole point is that the template system is meant to express presentation, not program logic. The actual job of every template engine is to parse a template and compile it into a native PHP class. As there is no need to repeat the whole process on each request made by a browser, each template is compiled only once (on the first request). Every subsequent request will receive the already compiled file [Class]. The Cache folder is where all compiled classes are stored .
- config : All configurations for the application (Db-credentials, routing) are written in Yaml. For better maintainability / accessibility related configurations are written into separate files (we could have used one single file for all configurations though) .
- Db_schema : Contains the SQL schema used by this project .
- notes : The developer can write down his/her notes. I usually exclude the content of this folder to be committed to Github.
- vendor : This folder is automatically generated by Composer, all libraries (which are defined in composer.json file) are downloaded into this folder. We don’t touch the content of this folder for any reason .
# cat /etc/httpd/conf.d/local.samplemvc.conf #NameVirtualHost *:80 DocumentRoot "/home/username/web/sample-MVC-with-Symfony2-components/web/" ServerName local.samplemvc ServerAlias local.samplemvc ErrorLog /var/log/httpd/local.samplemvc.error_log CustomLog /var/log/httpd/local.samplemvc.access_log combined ServerAdmin admin@myhost <directory "/home/username/web/symfony/sample-MVC-with-Symfony2-components/web/"> DirectoryIndex index.php Options All +Indexes +FollowSymLinks AllowOverride All Order allow,deny Allow from all
- src : This folder contains the logic of our application (Controllers, Models , Views and Custom Classes). Actually this is the place where we will spend our energy. Controllers have methods, each method is a task the Controller is capable to fulfill. For better manageability, tasks are grouped into separate Controllers, ie authentication related tasks go into an AuthController , user related tasks (CRUD operations) go into an UserController. Each task (Controller-method) is related with a template that exists in a directory with the name of the Controller ( for instance, UserController::listAction is related with /views/user/list.html.twig). That’s a standard implemented by all frameworks nowadays (a naming convention so to speak), it can be overwritten though (we will get to this on the next part of this article series) .
Let’s recap the workflow of our application :
- A request comes into our Domain (most likely from a browser) . Apache directs all requests to index.php (the FrontController), except when a matching file is found under the public_root folder (images, JS or CSS files) .
- FrontController’s responsibility is to call the corresponding Controller::action (based on the URI of the request)
- The Controller::action will execute a specific task (most likely, by off-loading tasks to Models and Services Classes) . The result of the task, a collection of data, will be passed over to the template where it will be rendered and returned to the browser.
Final thoughts (of this second part) :
No matter the size (or complexity) of an application, organizing its folders and files will pay off down the road (in terms of maintainability and teamwork). As there are no standards of how to structure a skeleton, just use your sense. The key point here is that the structure of the skeleton must be planned in such a way that any developer that might get involved into the project will get familiar instantly. On the next part of this article series, we will dig into the actual code. Thanks for reading …….