views:

85

answers:

5

There are plenty of PHP frameworks out there as many of you know, and I am interested in your thoughts on this: Zend Framework has so-called action controllers that must contain at least one action method, a method whose name ends in "Action". For example:

public function indexAction() {}

The word "Action" is important, without it you can't access the method directly via the URI. However, in some other frameworks like Kohana you have public and private methods, where public methods are accessible and private are not. So my question is which do you think is a better approach? From a secure point of view I would vote Zend's approach, but I am interested in knowing what others think.

A: 

Zend has this because in PHP 4 you didn't have private/public, so they had to rely on naming conventions. It's more secure to both have public/private and a naming convention indeed.

Frank Groeneveld
Hang on, I ZF *never* worked on PHP4, it was designed solely for PHP5+.
karim79
ZF was designed solely for PHP5.
Richard Knop
Your right. I wonder why they chose to use this naming scheme than, probably just for ease of understanding.
Frank Groeneveld
A: 

i'd say it's down to personal preference. there are many variations here, for example codeigniter's version of this is that any method name beginning with _ is private and anything else is a controller method.

speaking personally, i'd say that anything using built-in language controls (eg public function vs private function) would be the most intuitive.

edit : as frank says, the MOST SECURE method would be one using as many features as possible (eg private as well as method name).

oedo
Adding an underscore in front of non-public method names is a relict from PHP4 times, where you would indicate suggested visibility through that (not that it would have any effect). ZF uses this notation by convention too (although it is not backwards compatible with PHP4), likely with the intention to make visibility easy to spot in code. The action suffix in Controller method names is not to indicate visibility though.
Gordon
+1  A: 

It's preference really. Using some kind of naming convention is more versatile (and this is actually what Kohana 3 does now), since it allows for public methods that aren't actions, which can be useful.

Of course, the ideal solution is to use some kind of code metadata like .NET's attributes or Java's annotations, but unfortunately this feature doesn't exist in PHP.

Will Vousden
+1  A: 

Based on preference, I am good with the zend framework's approach. It has proper controller encapsulation. Yes you must add the word action and create a view script(optional) for you to access it via URL. Yet you may still use the private,protected and public functions within the controller for additional logic.

Hanseh
+1  A: 

This has less to do with security than it has to do with ZF's design. Like you said, the methods are not accessible when invoked through a URL, but that is solely due to how Zend Framework processes requests.

Quoting the reference guide:

The workflow of Zend_Controller is relatively simple. A request is received by Zend_Controller_Front, which in turn calls Zend_Controller_Router_Rewrite to determine which controller (and action in that controller) to dispatch.

Zend_Controller_Router_Rewrite decomposes the URI in order to set the controller and action names in the request. Zend_Controller_Front then enters a dispatch loop. It calls Zend_Controller_Dispatcher_Standard, passing it the request, to dispatch to the controller and action specified in the request (or use defaults).

The method names get formatted in Zend_Controller_Dispatcher_Abstract:

/**
 * Formats a string into an action name.  This is used to take a raw
 * action name, such as one that would be stored inside a Zend_Controller_Request_Abstract
 * object, and reformat into a proper method name that would be found
 * inside a class extending Zend_Controller_Action.
 *
 * @param string $unformatted
 * @return string
 */
public function formatActionName($unformatted)
{
    $formatted = $this->_formatName($unformatted, true);
    return strtolower(substr($formatted, 0, 1)) . substr($formatted, 1) . 'Action';
}

The Action suffix is hardcoded, so the Dispatcher will always look for an Action method, no matter what. So when you request /user/show/, the you'd call UserController::showAction() because of how the request is handled. It's not a security feature though or a replacement for Visibility. Make showAction() protected and you no longer have access to it through a URL either. And technically, you could very much call the non-action methods from a URI if you don't run them through the regular setup either. You could create your own Dispatcher and change how ZF formats action names easily.

What's nice about the Action Suffix, is it makes the action methods clearly distinguishable from other methods in the controller.

Gordon
In Kohana, all methods in a controller can be accessed via the URI unless you give the private/protected keyword. I can imagine many developers forgetting to put private/protected in some methods, and that leading to vulnerabilities. In Zend Framework, that won't happen as you must explicitly define what methods are accessible via URI with the suffix "Action".
rFactor
@Tower maybe, but like I said and shown above: having to write the Action suffix is not a **security** concept, but a design concept. It is **not** a replacement for visibility keywords. It is just a code convention.
Gordon
Agree with Gordon - it's not a security issue. Using "Action" particularly makes it clearer if you like to browse your source code folded to the method level - then the word "Action" tends to stand out a lot more than just public/private would
asgeo1