Twig recherche les variables en effectuant un isset sur la variable puis en recherchant, si l’isset est négatif, une méthode variable(), getVariable(), isVariable() ou __call(). Si aucune de ces méthodes n’est disponible une erreur est émise ou masquer suivant le paramètre strict_variables.
Utilisation des accesseurs intégrés à PHP.
Les accesseurs (manipulateurs/getters) php peuvent être utilisés sous la forme suivante :
class Test{
private $variable;
public function __isset($name){
switch($name){
case "variable": true;
default: return false;
}
}
public function __get($name){
switch($name){
case "variable":
if( ! isset($this->variable)){
$this->traitement();
}
return $this->variable;
}
}
}
La problématique résultante est que les appels internes vers la variable cible ne seront pas pris en compte. En effet, si à l’intérieur de la classe, un $this->variable est utilisée pour obtenir une variable non encore settée, aucune erreur ne sera émise, sans test. Et vous devrez dupliquer le code afin de lancer les traitement préalables.
Voila pourquoi il est grandement conseillé d’utiliser les accesseurs sous forme de get ou de is. A noter que l’utilisation de call entraine la même problématique.
A noter que si vous ne définissez pas la variable en tant que variable de classe, la problématique n’est plus technique mais organisationnelle. En effet les appels à la variables seront redirigés vers votre function __get, mais vous perdrez la visibilité des variables disponibles en entête.
Cas du ArrayAccess
Bug dans Array access avec extension
If i defined an class implementing ArrayAccess, the public property or method become not allowed for twig.
This behavior is present with extension installed in versions 1.6 and 1.7.
Code to reproduce :
“`php
define ("DEBUG", true);
require_once( __DIR__ . "/Twig/lib/Twig/Autoloader.php");
class Obj implements ArrayAccess{
private $collection = array();
public $var = "var_value";
function __construct(){
$this->collection['test'] = ‘test_value’;
}
public function offsetExists($key){return isset($this->collection[$key]);}
public function offsetGet($key){return $this->collection[$key];}
public function offsetSet($key, $value){throw new \Exception(”Documents souldn’t be write”);}
public function offsetUnset($key){throw new \Exception(”Documents souldn’t be write”);}
}
Twig_Autoloader::register();
$loader = new Twig_Loader_String();
$twig = new Twig_Environment($loader, array(
‘auto_reload’ => DEBUG,
’strict_variables’ => 1,
‘debug’ => DEBUG,
‘optimizations’ => 0,
));
echo “obj.test=”.$twig->render(”{{obj.test}}”, array(’obj’=>new Obj())).”\n”;
echo “obj.var=”.$twig->render(’{{obj.var}}’, array(’obj’=>new Obj())).”\n”;
“`
Result without extension and normally waited:
“`
obj.test=test_value
obj.var=var_value
“`
Result with extension
“`
obj.testtest_value
obj.var
Notice: Undefined index: var in /…/test_controleur.php on line 14
Call Stack:
0.0007 660944 1. {main}() /…/test_controleur.php:0
0.0300 4231496 2. Twig_Environment->render() /…/test_controleur.php:32
0.0328 4272488 3. Twig_Template->render() /…/Twig/lib/Twig/Environment.php:288
0.0328 4314344 4. Twig_Template->display() /…/Twig/lib/Twig/Template.php:250
0.0328 4314656 5. Twig_Template->displayWithErrorHandling() /…/Twig/lib/Twig/Template.php:239
0.0328 4314656 6. __TwigTemplate_57ce66ffa28dd3ec8adabcae87a9fd6b->doDisplay() /…/Twig/lib/Twig/Template.php:265
0.0328 4314872 7. twig_template_get_attributes() /…/Twig/lib/Twig/Environment.php(320) : eval()’d code:19
0.0329 4318080 8. Obj->offsetGet() /…/test_controleur.php:0