How not to develop on the Zend Framework
Hello! Recently turned up to work to finish a website on zend framework. The programmer, who began to develop this project is not managed in time, did not fulfill the requirements of the customer and in the end he was replaced. First time opening the source code, I was horrified by the amount of mistakes that allowed the developer and he claimed to a customer that is an experienced professional. Next I will try to tell you about some of the mistakes that was committed. This material will be useful for beginners ZF-programmers, as the user to do. Also, I will discuss some points not directly related to the framework, but also are shining examples of ignorance of developers.
the
Using built-in methods instead of writing their own
The first thing that immediately caught my eye — the execution of queries using the object model directly in the controller code, that completely negates all the benefits of MVC. To be clear about what speech I will give an example source code:
$model = new Model();
$some_data = $model->fetchAll(array('field1 = ?' => 1 'field2 = ?' => 0));
$all_data = $model->fetchAll();
Colored with dumpz.orgSuch mixing of logic was in each file of the controller, which is very disturbing reading code and fixing bugs, constantly there were any not so obvious dependencies overwritten important data. Accordingly not do so in any case impossible, even if you are developing a small project.
the
Appeal directly to the global arrays instead of accessing the Request object
From ZF is a very handy shell over global variables in an object of class Zend_Controller_Request_Http. This class provides us a lot of opportunities for data access and is used by the framework in the process dispatching. So you should not neglect the use of the request object.
the
the Lack of context-switching when necessary
For processing ajax requests you can use the so-called context-switch that provides a convenient way to change the format of the response. If you use json then in the init method of the controller to set something like the following:
$this->_helper->AjaxContext()->addActionContext('ajax-handler' 'json')->initContext('json');
Colored with dumpz.orgNow all the data transmitted in the view in action ajax-handler will be converted to json. This method is more preferable in comparison with view off and manual conversion of data to json.
the
Neglect of using Zend_Form and Zend_Validate
It is not necessary to use the php functions for data validation, since in ZF there is a very convenient validators that can be combined into groups and put on the processing of certain form fields. Using ZF-validators you reduce the chance that you miss something and thus make your applications more robust.
the
No validation
You must check all data you received from the user, and you should check them in the context of access rights a given user, for example, if you write the add/delete materials from the list of favourites and you have js-functions like the following then you should very good think:
function addObject(object_id, user_id) {
$.get('/realestate/favorite/oid/'+object_id+'/uid/'+user_id, function () {
$("#addfavorite"+object_id).hide();
});
}
}
function removeObject(object_id, user_id) {
if (user_id > 0) {
$.get('/profile/removefavorite/oid/'+object_id+'/uid/'+user_id, function () {
$("#removefavorite"+object_id).hide();
});
}
}
Colored with dumpz.orgAs it turned out later on server-side user_id is not checked for equality with the current user ID, which is a serious vulnerability
the
Using ACL instead of the controller class hierarchy
Almost every site has several access levels: guests, users, administrators, etc. to control the access rights statuses to certain parts of the site were used a hierarchy of controllers. Ie created a parent class for controllers of the admin class for other controllers in this parent class is executed something like this:
public function preDispatch() {
// here is an example of a global variable *fail*
if (!empty($_REQUEST['session'])) {
session_id($_REQUEST['session']);
} else {
$auth = Zend_Auth::getInstance();
if (!$auth->hasIdentity()) {
$this->_redirect('backoffice/auth/login');
}
}
}
Colored with dumpz.orgWhat's wrong this approach? First, it is very difficult is the redistribution of access rights. Secondly, it is difficult to support multiple roles. You can go on
For this purpose, in ZF, there is an excellent tool for creating lists of access rights or ACL. Personally I use a little plugin that checks the access rights of the user for the requested action/controller in the process dispatching. This method allows you to create access rights in a simple, easily changeable list, like this:
//Add the role
$this->addRole('guest');
$this->addRole('user' 'guest');
$this->addRole('manager' 'user');
//Add resources
$this->add(new Zend_Acl_Resource('guest_allow'));
$this->add(new Zend_Acl_Resource('index/index'),'guest_allow');
$this->add(new Zend_Acl_Resource('index/registration'),'guest_allow');
$this->add(new Zend_Acl_Resource('error/error'),'guest_allow');
$this->add(new Zend_Acl_Resource('user_allow'));
$this->add(new Zend_Acl_Resource('project/index'),'user_allow');
$this->add(new Zend_Acl_Resource('task/index'),'user_allow');
$this->add(new Zend_Acl_Resource('task/complete'),'user_allow');
$this->add(new Zend_Acl_Resource('task/assigned'),'user_allow');
$this->add(new Zend_Acl_Resource('manager_allow'));
$this->add(new Zend_Acl_Resource('project/add'),'manager_allow');
$this->add(new Zend_Acl_Resource('task/add'),'manager_allow');
$this->add(new Zend_Acl_Resource(' / index/add-user'),'manager_allow');
//Put right, by default all is forbidden
$this->deny(null null null);
$this->allow('guest' 'guest_allow' 'show');
$this->allow('user''user_allow' 'show');
$this->allow('manager''manager_allow' 'show');
Colored with dumpz.orgthe
Filtering data in the form fields responsible for the password
Never, never filter the data that comes from a password field! This can lead to long trying to find the reason why users then it should work. In my case the reason was the following:
$f = new Zend_Filter_StripTags();
$pwd = $f->filter($this->_request->getPost('pwd'));
Colored with dumpz.orgGiven that the passwords are stored in encrypted form and never displayed, the presence of tags, or gaps, in no way can lead to vulnerabilities, respectively, and filtering to anything
the
to Provide localisation you need to advance
Often somehow the localization of the project submitted to the second plan, i.e. first all the gash, and then screw the localization. This is a big mistake, because then screwed it will be very difficult. Will need to find all not localized strings, and it is a very long process. Much easier to just properly handle strings, which require multilingual support.
the
avoiding the use of ViewHelpers
You should always use view helpers baseUrl and url to build a url and the paths to the static resources. This is important because you can't be sure how will is app from other developers. In our case the path was formed as if the app is at the root of the host that has created a number of problems when deployed on my machine.
the
Using text constants instead of Boolean variables
In the end I want to tell you about an interesting method of replacing logical variables by rows. In the code I found something like this:
if ($a > $b)
else
$this->view->result = 'fail';
Colored with dumpz.orgThere is no further explanation required, I think the last line eloquently does it for me.
the
Conclusion
This is not a complete list of errors that were found in the process of finalizing the project, but the key I described. I hope that someone reading this material will become to write better code. Thank you for your attention!
Комментарии
Отправить комментарий