Adding PUT variables to Request Object in Zend Framework
Its very simple: I have extended Zend_Controller_Action with my own, and all controllers inherit from here. This has a routeAction() which grabs the incoming variables from a PUT request and sets them as parameters within the usual $this->getRequest() scope, then forwards on the request. Here is my class:
class My_Controller_Action extends Zend_Controller_Action
{
public function routeAction()
{
// handle grabbing PUT vars
if($this->getRequest()->isPut()) {
parse_str($this->getRequest()->getRawBody(), $params);
foreach($params as $key => $value) {
$this->getRequest()->setParam($key, $value);
}
}
$this->_forward(strtolower($this->getRequest()->getMethod()));
}
}
So in my controller code, I simply call out to $this->getRequest()->getParam(‘name’) or whatever, and in my tests I can set those parameters as I showed in my other article.
I hope this makes sense, its one of those things I set up once and use a lot (and now I’ll be able to refer to how I did it!), if you have any queries, comments, improvements or if this helps you then please leave a comment – I haven’t come across anyone else doing anything similar but I know there must be, so let me know!
in your code you have:
[geshi lang=php]
foreach($params as $key => $value) { $this->getRequest()->setParam($key, $value);
}
[/lang]
wouldn’t that be better to have the object returned by the getRequest cached so that you don’t spend time calling it in each loop?
eg
[geshi lang=php]
$myReq = $this->getRequest();
foreach($params as $key => $value) {
$myReq->setParam($key, $value);
}
[/lang]
BinaryKitten: You certainly could do – I know my system deals only with about five incoming parameters so the change would be tiny. In principle though you are quite correct and repeatedly fetching something in a loop is a Bad Thing (TM)
I believe this is available since ZF 1.9 as a controller plugin:
http://framework.zend.com/manual/en/zend.controller.plugins.html#zend.controller.plugins.standard.puthandler
It’s probably intended as a companion to Zend_Rest_Controller but it works everywhere and without overriding anything, which is nice. :)
Ross: I didn’t know that! This project started before 1.9 so I don’t have it but I’ll look it up for next time
Lorna,
you should consider putting the parse_str() logic into the request object, rather than a controller. You are dealing with details of how request works (namely, the raw request data), thus you are coupling your controller to the request more tightly than you’d have to. Plus, by putting that logic into the request, it’s easier to reuse.
Stefan
Or one can have some kind of RequestHandler class which responsibility is to populate the Request object. This happens differently for example if you application is called from command line.
A step further: the action controller can defines its parameters via the parameter list and the front controller can populate them via Reflection API. This way you controller seems like a real function.
@Lorna: to consider what to put to a controller is a good technique is to think about what would be if your controller should work in CLI.
I like the sound of these – can either of you refer me to an example of how I would actually do this? I’m a bit of a ZF newbie so although I can usually get things working, I’m sure there are better ways like these you suggest