Zend Framework tips and tricks
Zend Framework tips and tricks
Translation of the article Zend Framework tips and tricks.
author: Juozas devBlog
Nice to use good tools, however You need to be sure that you're using them properly and not just encode "it seems to work, well, okay." For this reason I decided to write a list of things I always keep in mind when taking to support someone else's project or advise how to start.
Most of the recommendations focus on ease of testing, ease of support and other good coding practices. If You are not familiar with these recommendations, it is advised to start reading as soon as possible. I am sure that You are making these mistakes and don't even realize how wrong you are. Believe me, very soon You will significantly improve your development skills.
Separate logic
This statement is most obvious, but, believe me, I've found errors in every project in which he participated (more than 10 with the Zend Framework for the last six months). If it's a controller, it should not be business logic if it is model, it should not be processing POST parameters, etc. Logic should be in place and must be separated from the forms, and bootstrap', views, helpers, etc.
Move all logic from controller to model or service (service). Use the form only to validate and filter data, do not process the forms data. Hide session and identify users, carry out all necessary operations in one place and provide API functions to use in other parts of the project. I can go on and on, but I hope the idea becomes clear. In the end, You realize that something, when you start to test the code: when just to test the form, You will have to set frontController, request, cookie, and mail server.
Global variables
If You haven't seen this videos, look, please, right now, you will not regret. Global variables create a lot of problems when testing and contrary to the concepts of Object-Oriented Programming. This includes obtaining values of $_SERVER, $_SESSION, etc., all these values are available via methods of the query objects (see Zend_Controller_Request_Http), or separate classes, for example Zend_Session.
And again I want to mention about the ease of testing, because this is what You must always remember that developing a program. The test should not modify global variables. To get the value of the test needs to use the methods of the objects which return the desired values (e.g. IP). Zend Framework provides convenience classes to access all global variables is a sin not to use them.
Use shape values, not query
This recommendation is very easy to follow.
Look at the following example code:
Once the form is checked (and therefore the values are filtered), still used raw request data $this->_request->getPost(). You just lost many cool features Zend_Form, for example, ignored items (button "submit"). Moreover, the form does not use filters, but because You set up the filters, isn't it? In addition, I can convey to the model that you want, and the model itself needs to run checks on the data. So in the method $form- > getValues() must be implemented not just functionality checks, but also filters.
In this example, excessive use of the form's method populate(). This method is designed to set initial form values. In case of error, the isValid() method itself will establish the desired values, so additional functions to set values, there is no need.
do Not use exit()/die()
The first thing I do is remove all calls to exit() and rework them using exception or return statement. There are very few cases when the use of one of these functions can be considered justified. For example, let's consider this code in a controller action:
The first problem is to think that $this->_redirect() will call exit() and thus the action execution is completed. Although this is indeed the case, You should avoid such cases. Such challenges make it impossible to generate events post*. Moreover, it makes testing impossible or incorrect. Zend_Test disables the exit() call in the assistants to controller, so during testing You can't test the authentication. To fix this problem, just add a return before executing the redirect (return $this->_redirect(‘/’)) and everything will be fine.
Moreover, the second exit() is absolutely useless and makes the code not suitable for testing. To remedy the situation, you can add return, it will not execute the subsequent code, the view will not be redrawn, because the viewRenderer controls all the redirection, and if you find such, does nothing. From my experience, after you save the form data in code, it is sufficient to put only a redirect without exit().
Use framework instead of PHP
At first it may seem a little strange, but if You are using a framework (in this case Zend Framework), do not start to transfer techniques and methods from a PHP application five years ago. As an example, here (the controller action):
I don't even know how to start... All this logic is already inserted in the response object (response), i.e. You can do the following:
These two fragments appear to be similar, but it's not. You can very easily verify that code does not work with global variables
(header () is a function of the global variable) and request processing is not interrupted. The controller does not output any data (and therefore not using echo), it simply gets the request object and sends the response object, that's all. The data output controller similarly interrupts the process execution and call exit(), so don't forget to make sure you are not interrupted this stream.
And more small additions
In Application.ini described property includePaths which can be used to add additional paths to the path variable. Although it works perfectly, I recommend not to use this opportunity, because these paths are added whenever you create a new instance of the application (this is in 1.9, but may change in the future). If You're testing controllers, you probably each time before you create a new instance. Having done a couple of hundred tests, You'll find that the performance of the times lower and lower. To find and fix the problem it took me a few hours, I still remember all of it.
If You use jQuery or another view helper for javascript, use all its features. I.e. adding additional resources and code, use a function of type addJavascriptFile(), addJavascript(), addStylesheet(), addOnload (), etc. If You insert javascript directly into the view, everything will work fine, but when using the view helper is all of the code necessary to put in one place and not scattered around different places.
Opinion
This is just a small part of the challenges I've faced in my practice, I have another story to tell. Hope You also share your secrets. I want to believe that I gave You some useful ideas of how to work with Zend framework, and Your code will be beautiful, and the design time will be reduced because everything will be clear and well organized.
Petrulevich, Sergey
petrelevich@yandex.ru
www.SmartyIT.ru
Fellow did translation of the article he has no account on Habre,
so publish.
Article based on information from habrahabr.ru
Translation of the article Zend Framework tips and tricks.
author: Juozas devBlog
Nice to use good tools, however You need to be sure that you're using them properly and not just encode "it seems to work, well, okay." For this reason I decided to write a list of things I always keep in mind when taking to support someone else's project or advise how to start.
Most of the recommendations focus on ease of testing, ease of support and other good coding practices. If You are not familiar with these recommendations, it is advised to start reading as soon as possible. I am sure that You are making these mistakes and don't even realize how wrong you are. Believe me, very soon You will significantly improve your development skills.
Separate logic
This statement is most obvious, but, believe me, I've found errors in every project in which he participated (more than 10 with the Zend Framework for the last six months). If it's a controller, it should not be business logic if it is model, it should not be processing POST parameters, etc. Logic should be in place and must be separated from the forms, and bootstrap', views, helpers, etc.
Move all logic from controller to model or service (service). Use the form only to validate and filter data, do not process the forms data. Hide session and identify users, carry out all necessary operations in one place and provide API functions to use in other parts of the project. I can go on and on, but I hope the idea becomes clear. In the end, You realize that something, when you start to test the code: when just to test the form, You will have to set frontController, request, cookie, and mail server.
Global variables
If You haven't seen this videos, look, please, right now, you will not regret. Global variables create a lot of problems when testing and contrary to the concepts of Object-Oriented Programming. This includes obtaining values of $_SERVER, $_SESSION, etc., all these values are available via methods of the query objects (see Zend_Controller_Request_Http), or separate classes, for example Zend_Session.
And again I want to mention about the ease of testing, because this is what You must always remember that developing a program. The test should not modify global variables. To get the value of the test needs to use the methods of the objects which return the desired values (e.g. IP). Zend Framework provides convenience classes to access all global variables is a sin not to use them.
Use shape values, not query
This recommendation is very easy to follow.
Look at the following example code:
$form = new Form();
if ($this->_request->isPost())
{
if ($form->isValid($this->_request->getPost())
{
$model = new Model($this->_request->getPost());
$model- > save();
}
else
{
$form- > populate($this->_request->getPost());
}
}
* This source code was highlighted with Source Code Highlighter.
Once the form is checked (and therefore the values are filtered), still used raw request data $this->_request->getPost(). You just lost many cool features Zend_Form, for example, ignored items (button "submit"). Moreover, the form does not use filters, but because You set up the filters, isn't it? In addition, I can convey to the model that you want, and the model itself needs to run checks on the data. So in the method $form- > getValues() must be implemented not just functionality checks, but also filters.
In this example, excessive use of the form's method populate(). This method is designed to set initial form values. In case of error, the isValid() method itself will establish the desired values, so additional functions to set values, there is no need.
do Not use exit()/die()
The first thing I do is remove all calls to exit() and rework them using exception or return statement. There are very few cases when the use of one of these functions can be considered justified. For example, let's consider this code in a controller action:
if (!$this->userHasPermissions())
{
$this->_redirect('/');
}
$form = new Form_Add();
if (//submit form)
{
// save with $form->getValues();
$this->_redirect('/index');
exit();
}
// some other actions
* This source code was highlighted with Source Code Highlighter.
The first problem is to think that $this->_redirect() will call exit() and thus the action execution is completed. Although this is indeed the case, You should avoid such cases. Such challenges make it impossible to generate events post*. Moreover, it makes testing impossible or incorrect. Zend_Test disables the exit() call in the assistants to controller, so during testing You can't test the authentication. To fix this problem, just add a return before executing the redirect (return $this->_redirect(‘/’)) and everything will be fine.
Moreover, the second exit() is absolutely useless and makes the code not suitable for testing. To remedy the situation, you can add return, it will not execute the subsequent code, the view will not be redrawn, because the viewRenderer controls all the redirection, and if you find such, does nothing. From my experience, after you save the form data in code, it is sufficient to put only a redirect without exit().
Use framework instead of PHP
At first it may seem a little strange, but if You are using a framework (in this case Zend Framework), do not start to transfer techniques and methods from a PHP application five years ago. As an example, here (the controller action):
$object = new Some_Object();
$image = $object->generateImage();
header ('Content-type: image/jpeg');
echo $image;
* This source code was highlighted with Source Code Highlighter.
I don't even know how to start... All this logic is already inserted in the response object (response), i.e. You can do the following:
$this->getResponse()->setHeader("Content-type" 'image/jpeg');
$this->getResponse()->setBody($image);
* This source code was highlighted with Source Code Highlighter.
These two fragments appear to be similar, but it's not. You can very easily verify that code does not work with global variables
(header () is a function of the global variable) and request processing is not interrupted. The controller does not output any data (and therefore not using echo), it simply gets the request object and sends the response object, that's all. The data output controller similarly interrupts the process execution and call exit(), so don't forget to make sure you are not interrupted this stream.
And more small additions
In Application.ini described property includePaths which can be used to add additional paths to the path variable. Although it works perfectly, I recommend not to use this opportunity, because these paths are added whenever you create a new instance of the application (this is in 1.9, but may change in the future). If You're testing controllers, you probably each time before you create a new instance. Having done a couple of hundred tests, You'll find that the performance of the times lower and lower. To find and fix the problem it took me a few hours, I still remember all of it.
If You use jQuery or another view helper for javascript, use all its features. I.e. adding additional resources and code, use a function of type addJavascriptFile(), addJavascript(), addStylesheet(), addOnload (), etc. If You insert javascript directly into the view, everything will work fine, but when using the view helper is all of the code necessary to put in one place and not scattered around different places.
Opinion
This is just a small part of the challenges I've faced in my practice, I have another story to tell. Hope You also share your secrets. I want to believe that I gave You some useful ideas of how to work with Zend framework, and Your code will be beautiful, and the design time will be reduced because everything will be clear and well organized.
Petrulevich, Sergey
petrelevich@yandex.ru
www.SmartyIT.ru
Fellow did translation of the article he has no account on Habre,
so publish.
Comments
Post a Comment