我已经创建了一个 Template
类来管理视图及其相关数据。它实现了Iterator
和ArrayAccess
,并允许“子模板”以便于使用,如下所示:
<p><?php echo $template['foo']; ?></p>
<?php foreach($template->post as $post): ?>
<p><?php echo $post['bar']; ?></p>
<?php endforeach; ?>
无论如何,我认为创建一个名为 hash()
的类非常有用,而不是使用内联核心函数,例如date()
或TemplateData
,它将充当模板中存储的任何数据的包装。
这样,我可以添加一些常用的格式化方法列表,例如:
echo $template['foo']->asCase('upper');
echo $template['bar']->asDate('H:i:s');
//etc..
当通过控制器中的$template['foo'] = 'bar';
设置值时,'bar'
的值将存储在其自己的TemplateData
对象中。
我使用了魔法__toString()
所以当你回显一个TemplateData
对象时,它会转换为(string)
并转储它的值。但是,尽管mantra 控制器和视图不应该修改数据,每当我做这样的事情时:
$template['foo'] = 1;
echo $template['foo'] + 1; //exception
它死于Object of class TemplateData could not be converted to int
;除非我重新 $template['foo']
到一个字符串:
echo ((string) $template['foo']) + 1; //outputs 2
排除了必须跳过那个篮圈的目的。 是否存在此类行为存在的变通方法,或者我应该这样做,是否偶然阻止了视图中的数据修改?
答案 0 :(得分:1)
Echo试图回应$template['foo'] + 1
的结果。由于$template['foo']
是TemplateData
类型的对象,而1
是int
,因此您收到错误。在这种情况下,((string) $template['foo'])
不是“重铸”,它是第一次投射。
答案 1 :(得分:1)
PHP不支持operator loading。如果您希望能够执行添加(或与此相关的任何其他操作员),则需要为要支持的每个操作员提供方法。很可能在基本模板类上实现它就足以满足常见情况,允许在以后必要时进行扩展。虽然在您的对象上使用(string)
是一种捷径,但我建议不要这样做。
答案 2 :(得分:0)
我稍微改变了我的实现,它似乎暂时有效;我已将__invoke()
方法添加到TemplateData
类,该类返回$_data
属性,未更改,无需进行类型转换。所以在实践中:
//in controller
$template['foo'] = 'bar';
$template['abc'] = 123;
//in view
echo $template['foo'](); //bar
echo $template['foo']->asHash('md5'); //37b51d194a7513...
echo $template['abc'](); //123
echo $template['abc']() + 123; //246
echo $template['abc']->asHash('md5'); //202cb962ac5907...
//__invoke also takes $function and $arguments for alternative syntax
echo $template['foo']('asHash', array('md5')); //37b51d194a7513...
我想,既然我征服了这座山,我的下一步就是以某种方式允许链接:
echo $template['foo']->asHash('md5')->asCase('upper');
然而,这似乎很难做到。跟踪“连锁状态”是我之前尝试过但没有成功的事情。在某种意义上,__invoke()
会很容易(但很混乱):
echo $template['foo'](
array('asHash', 'asCase'), //ordered array of method names
array(array('md5'), array('upper')) //ordered array of method argument arrays
);
任何人都可以看到这方面的问题,或其他方法的其他推理吗?