Design, CG Graphics & Inspiration
How you shouldn’t develop in Zend Framework

How you shouldn’t develop in Zend Framework

The following material will be useful for beginners in ZF-programming, as a kind of instructions on what you shouldn’t do in Zend Framework. Also, I’m going to tell you about some things that are not directly related to the framework, but they are the striking examples of ignorance of different developers.

Using the built-in methods of model, instead of writing your own

The first thing that caught my eye was running queries through a model’s object directly in the controller code, and that completely negates all the benefits of MVC. To make it clear I’ll give you an example of source code:

$model = new Model();
$some_data = $model->fetchAll(array('field1 = ?' => 1, 'field2 = ?' => 0));
$all_data = $model->fetchAll();

Such mixing of logic was in each file of the controller, which prevented reading the code and fixing the bugs, some unobvious dependences constantly appeared there, and important data was overwritten. Accordingly, you shouldn’t do that in any case, even if you’re developing a small project.

Appeal directly to the global arrays instead of turning to the Request object

In ZF there is a very handy shell over global variables as an object of Zend_Controller_Request_Http class. This class provides us with many opportunities for data access and is being used by the framework in the process of dispatching. So do not neglect using the request object.

The absence of context-switching when it is necessary

To implement the processing of ajax-requests you can use the so-called context-switch that provides a convenient way to change the format of the answer. If you are using json then in the init method of the controller you should set something like this:

$this->_helper->AjaxContext()->addActionContext('ajax-handler', 'json')->initContext('json');

Now all the data transmitted in the view in ajax-handler action, will be converted to a json format. This method is more preferable to one of disabling the view and manually converting data into json.

Neglect of using Zend_Form and Zend_Validate

You shouldn’t use the php functions for data validation, because ZF has very convenient validators that can be grouped and placed on the handling of certain form fields. Using the ZF-validators you reduce the chance that you’ll miss something, and thus make your applications more robust.

Lack of data validation

You should check all the data you receive from the user, and you should check them in the context of the user’s access rights, for example, if you write the addition / removal of materials from the favorite list and you have js-functions like given below, then you should think about it:

function addObject(object_id, user_id) {  
    if (user_id > 0) {       
        $.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();
        });
    }
}

As it turned out later the server-side user_id was not checked for equality of the current user ID, which is a serious vulnerability.

Using a hierarchy class of controllers instead of ACL

Almost every site has several levels of access: visitors, users, administrators, etc. The hierarchy of controllers was used in order to control access rights status to a certain parts of the site. A parent class for admin controllers was created, with the class for the other controllers. Something like this was performed in this parent class:

 public function preDispatch() {
                // Here is the example of global variables *fail*
        if (!empty($_REQUEST['session'])) { 
            session_id($_REQUEST['session']);
        } else {
            $auth = Zend_Auth::getInstance();
            if (!$auth->hasIdentity()) {
                $this->_redirect('backoffice/auth/login');
            }
        }
    }

What’s wrong with this approach? Firstly, the difficult thing is the redistribution of access rights. Secondly, it is difficult to support multiple roles. And we can go on and on.
For these purposes ZF has a wonderful tool for the formation of the ACL. Personally, I use a small plugin, which checks user’s access rights to the requested action / controller during the dispatching process. This method allows you to create the access rights in a simple, easily mutable list, like this:

//Add rolees
        $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('index/logout'),'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');
        
        //Insert the allowance rights, everything is disallowed on default
        $this->deny(null, null, null);
        $this->allow('guest', 'guest_allow', 'show');
        $this->allow('user','user_allow', 'show');
        $this->allow('manager','manager_allow', 'show');

Filtering data in the form fields that are responsible for the password

Never filter the data that comes from the password field! You can face with long attempts to find out the reason why users can not login. In my case the reason was the following:

$f = new Zend_Filter_StripTags();
$pwd = $f->filter($this->_request->getPost('pwd'));

Given that the passwords should be stored in encrypted form and should never be displayed, presence of tags, or spaces, cannot lead to vulnerabilities, respectively, there is no need in filtering.

It’s better to provide the localization in advance

Often, for some reason, the localization of the project is being pushed to the sidelines, ie first, you’ll make up everything, and only then you’ll implement the localization. This is a big mistake, because it will be very difficult. You will need to find lines that are not localized, and it’s a very long process. It is much easier to handle at once the lines that require multi-language.

Refusal to use ViewHelpers

You should always use the url helpers and baseUrl to generate the url and paths to the static resources. It’s very important, because you can’t be sure how the application will be located at other developers. In our case, the paths were formed in a way as if the application is at the root of the host, which created some problems while running it on my computer.

Using text constants instead of the logical variables

In conclusion, I would like to tell you about an interesting way to replace logical variables with lines. I’ve found something like this in the code:

if ($a > $b)
    $this->view->result = 'ok'
else
    $this->view->result = 'fail';

Conclusion

This is not an exhaustive list of errors that were found in the process of finalizing the project, but I have described the basic. I hope that people who read this stuff will start to write a better code. Thank you for your attention!

  • dizballanze,
  • July 11, 2011

SHARE THIS POST

Subscribe for the hottest posts

Subscribe to our email newsletter for useful tips and freebies.