我写了我自己的树枝扩展来做到这一点。你会以我想要的方式使用它:
{% set keyVariable = 'propertyName' %}
{{ obj.access(keyVariable) }}
{# the above prints $obj->propertyName #}
就这个:
// filename: Acme/MainBundle/Extension/AccessTwigExtension.php
namespace Acme\MainBundle\Extension;
class AccessTwigExtension extends \Twig_Extension
{
public function getFilters()
{
return array(
'access' => new \Twig_Filter_Method($this, 'accessFilter'),
);
}
public function getName()
{
return 'access_twig_extension';
}
// Description:
// Dynamically retrieve the $key of the $obj, in the same order as
// $obj.$key would have done.
// Reference:
// http://twig.sensiolabs.org/doc/templates.html
public function accessFilter($obj, $key)
{
if (is_array($obj)) {
if (array_key_exists($key, $obj)) {
return $obj[$key];
}
} elseif (is_object($obj)) {
$reflect = new \ReflectionClass($obj);
if (property_exists($obj, $key) && $reflect->getProperty($key)->isPublic()) {
return $obj->$key;
}
if (method_exists($obj, $key) && $reflect->getMethod($key)->isPublic()) {
return $obj->$key();
}
$newKey = 'get' . ucfirst($key);
if (method_exists($obj, $newKey) && $reflect->getMethod($newKey)->isPublic()) {
return $obj->$newKey();
}
$newKey = 'is' . ucfirst($key);
if (method_exists($obj, $newKey) && $reflect->getMethod($newKey)->isPublic()) {
return $obj->$newKey();
}
}
return null;
}
}
要在我的程序中使用它,我还必须在依赖注入中添加几行:
//filename: Acme/MainBundle/DependencyInjection/AcmeMainInjection.php
// other stuff is here....
public function load(array $configs, ContainerBuilder $container)
{
// other stuff here...
$definition = new Definition('Lad\MainBundle\Extension\AccessTwigExtension');
$definition->addTag('twig.extension');
$container->setDefinition('access_twig_extension', $definition);
// other stuff here...