Automatic variable escaper for Zend Framework
Can you recommend any good solution for automatic view variable escaping for Zend Framework 1.x?
I have tried so far:
- ZF2 implementation; looks like it does not escape variables syntax like this:
$this->var->object()->string
- gnix-view, very nice, but has a nasty recursion bug
- custom solutions based on
view streams
, similar to Rob Allen's escaper, but 开发者_开发技巧parsing syntax with regex always fails - Twig (no good support for view helpers and layout)
Here is my solution
/**
* Purifies all data passed to view
*
* @author miholeus
*/
class HTMLPurifier_View extends Zend_View {
protected $_vars = array();
public function __set($key, $val)
{
if(is_string($val)) {
$purified = $this->escape($val);
} elseif(is_array($val)) {
$purified = array_map(array($this, 'traverseSingle'), $val);
} else { // other types: integers, bools, objects
$purified = $this->traverseSingle($val);
}
$this->_vars[$key] = array(
'raw' => $val,
'purified' => $purified
);
return $this;
}
public function getRaw($key)
{
if(isset($this->_vars[$key])) {
return $this->_vars[$key]['raw'];
}
return null;
}
public function __get($key)
{
if(isset($this->_vars[$key])) {
return $this->_vars[$key]['purified'];
}
return null;
}
private function traverseSingle($element)
{
if(is_object($element)) {
$reflect = new ReflectionObject($element);
foreach ($reflect->getProperties(ReflectionProperty::IS_PUBLIC) as $prop) {
$element->{$prop->getName()} = $this->escape($element->{$prop->getName()});
}
return $element;
} else {
return $this->escape($element);
}
}
}
All you need to do is to set it as your view in bootstrap.
if i would think to make an automatic escaper i would create a ZF plugin that run in postDispatch
:
postDispatch() is called after an action is dispatched by the dispatcher. This callback allows for proxy or filter behavior. By altering the request and resetting its dispatched flag (via Zend_Controller_Request_Abstract::setDispatched(false)), a new action may be specified for dispatching. source
mybe some use of htmlprifier would be a smart job :)
class Automatic_Escaper extends Zend_Controller_Plugin_Abstract{
public function postDispatch(Zend_Controller_Request_Abstract $request)
{
$response = $this->getResponse();
$htmlpurifier = Zend_Registry::get('purifier');
$safe = $htmlpurifier->purify($response);
return $this->setResponse($safe);
}
}
I hope I explained my idea regardless of the status the sample above .
精彩评论