📜 ⬆️ ⬇️

Zend Framework Tips and Tricks

Zend Framework Tips and Tricks

Translation of the article Zend Framework tips and tricks .
by Juozas devBlog

It's nice to use good tools, but you have to be sure that you use them properly, and not just encode "it seems to work, well, okay." For this reason, I decided to write a list of things that I always keep in mind when I accept someone’s project for support 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, I advise you to start reading as soon as possible. I am sure that you are making the mistakes described here and do not even suspect how wrong you are. Believe me, very soon you will significantly improve your development skills.

Separate logic
This statement is most obvious, however, believe me, I found errors in every project I participated in (more than 10 with the Zend Framework over the past six months). If it is a controller, there should be no business logic in it, if it is a model, it should not contain processing of POST parameters, etc. The logic should be in its place and should be separated from the forms, bootstrap, views, helpers, etc.

Transfer all the logic from the controller to the model or service . Use the form only for checking and filtering data; do not process data in forms. Hide sessions and user identification, perform all necessary operations in one place and provide API functions for use in other parts of the project. I can go on and on, but I hope that the idea becomes clear. In the end, you will realize that something is not right when you start testing the code: when in order to just test the form, you will have to set up the frontController, request, cookie and mail server.

Global variables
If you have not seen this video , please see right now, you will not regret. Global variables create many problems during testing and contradict the concepts of Object Oriented Programming. This concerns getting $ _SERVER values, $ _SESSION, etc., all of these values ​​are available through the methods of the request objects (see Zend_Controller_Request_Http) or individual classes, such as Zend_Session.

And again I want to mention the ease of testing, because this is what you constantly have to remember when developing a program. The test should not modify global variables. To obtain a value, the test must use the methods of the objects that return the required values ​​(for example, IP). Zend Framework provides very convenient classes for access to all global variables, it is a sin not to use them.

Use form values, not request
This recommendation is very easy to follow.
Look at the following code example:

$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 .


After the form has been verified (and therefore the values ​​are filtered out), the raw request data is still used $ this -> _ request-> getPost (). You simply lose many interesting features of Zend_Form, for example, ignored elements (“submit” buttons). Moreover, the form does not use filters, and you are adjusting the filters, right? In addition, I can transfer anything to the model, and the model itself must perform data checks. So, in the $ form-> getValues ​​() method, not only the check functionality, but also the filters should be implemented.

In this example, the form method populate () is overused. This method is designed to set the initial form values. In case of an error, the isValid () method will set the required values ​​itself, therefore there is no need for an additional function to set values.

Do not use exit () / die ()
The first thing I do is remove all exit () calls and redo them using exceptions or a return statement. There are very few cases where the use of one of these functions can be considered justified. For example, let's consider the following controller action code:

if (!$ this ->userHasPermissions())
{
$ this ->_redirect( '/' );
}
$form = new Form_Add();
if ( //submit form)
{
// save with $form->getValues();
$ this ->_redirect( '/index' );
exit();
}
// -

* This source code was highlighted with Source Code Highlighter .


The first problem is to think that $ this -> _ redirect () will call exit () and thus the execution of the action will be completed. Although this is indeed the case, you should avoid such incidents. Such calls make it impossible to generate post * events. Moreover, this makes testing impossible or incorrect. Zend_Test disables the exit () call in the controller helper, so you cannot test permissions verification during testing. To fix this problem, simply add return before performing the redirect (return $ this -> _ redirect ('/')) and everything will be fine.

Moreover, the second exit () is absolutely useless and makes the code unsuitable for testing. To correct the situation, it is enough to add a return, it will not allow the following code to be executed, the view will not be redrawn, because The viewRenderer helper controls all redirections, and if it finds one, it does nothing. Based on my experience, after saving the form data, it is enough to put only redirection into the code, of course, without exit ().

Use framework instead of PHP
At first, this may seem a bit strange, but if you are using a framework (in this case, the Zend Framework), do not begin to transfer the techniques and methods from a PHP application five years ago. Like, for example, here (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 where to start here ... All this logic is already inserted into the response object, 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 may seem the same, but they are not. You can easily make sure that the code does not work with global variables.
(header () is a global variable function) and request processing is not interrupted. The controller does not output any data (therefore echo is not used), it simply receives the request object and sends the response object, and that’s all. Data output by the controller also interrupts the execution of the process in the same way as the exit () call, so make sure that you do not interrupt this thread .

And small additions
The Application.ini describes the includePaths property, which is used to add additional paths to the path variable. Although it works perfectly, I recommend not using this feature because these paths are added whenever you create a new instance of the application (this is the case in 1.9, but may change in the future). If you are testing controllers, then surely every time before starting you create a new instance. Having done a hundred or two tests, you will find that the performance times from lower and lower times. It took me a few hours to find and correct the error, I still remember it all.

If you use jQuery or another view helper for javascript, use all its features. Those. to add additional resources and code, use functions like addJavascriptFile (), addJavascript (), addStylesheet (), addOnload (), etc. If you insert javascript directly into the view, everything will work fine, but when using the view helper, you must put all the code in one place and not scatter it in different places.

Conclusion
This is just a small part of the problems and tasks that I encountered in my practice, I still have a story to tell. I hope you share your secrets too. I want to believe that I have given you some useful ideas on how to work correctly with the Zend framework, and your code will become more beautiful, and the development time will be reduced, since everything will be transparent and well organized.

Petrelevich Sergey
petrelevich@yandex.ru
www.SmartyIT.ru

Comrade made a translation of the article , he does not have an account on Habré,
therefore publish.

Source: https://habr.com/ru/post/84351/


All Articles