Comment puis-je lancer le constructeur et le destructeur défini par le trait avec le constructeur de classe et le destructeur. Par exemple,
trait Audit { public function __construct() { parent::__construct(); // Doesn't work... $this->_name = __CLASS__; $this->AuditAction('Started'); } public function __destruct() { parent::__destruct(); // Doesn't work... $this->AuditAction('Ended'); echo $this->_log; } public function AuditAction($n) { $this->_log .= $this->GetCurrentTimeStamp() . ' ' . $this->_name . ": $n" . PHP_EOL; } private function GetCurrentTimeStamp() { return (new DateTime())->format('[Y-m-d H:i:s]'); } private $_name, $_log = ''; } class C { use Audit; public function __construct() { } public function __destruct() { } } $c = new C();
3 Réponses :
Le constructeur et destructeur de C auront la priorité sur le constructeur de trait et le destructeur lorsque la classe est composée: p>
Un élément hérité d'une classe de base est remplacé par un membre inséré par un trait.
L'ordre de priorité est que les membres de la classe actuelle remplacent les méthodes de trait forts>, qui en retour sont héritées de méthodes héritées. p> blockQuote> Source: http://php.net/traits P>
En d'autres termes, retirez le constructeur vide et le destructeur de C et le constructeur et destructeur du trait seront utilisés. Il n'ya aucun moyen de faire fonctionner ce travail avec les traits, le constructeur et le destructeur, car les traits ne fonctionnent pas comme un héritage régulier. P>
En général, je conseillerais de donner des traits leurs propres constructeurs ou destructeurs, car vous ne pouvez pas instantiaire de traits. Vous instaniez d'une classe ayant em> un trait et que la classe doit être contrôlée. Envisagez d'ajouter un
Oncreate () Code> ou
OnDestroy () CODE> Méthode au trait et les appelez à partir des méthodes magiques appropriées sur C. Vous pouvez obtenir la même chose en aliasant les traits __construction en C, mais je pense que ces eaux descendent la sémantique. P>
Ce n'est pas correct. Il est possible d'appeler des méthodes du trait remplacées par la classe qui utilise le trait. Il suffit de changer le nom des méthodes dans le trait avec autre chose.
@Aerendir Si ma lecture de la source C est correcte, un CTOR aliasé ou DTOR ne contiendra plus les drapeaux de la fonction CTOR ou DTOR. Cela implique qu'il est techniquement pas possible i>, car ils ne sont que des méthodes régulières alors. Cependant, vous avez évidemment raison de pouvoir les exécuter comme méthodes régulières i> en aliasant et qui résoudra efficacement le problème de l'OP. Mais c'est plus comme appeler une personnalisation oncreate () code> ou
OnDestroy () code> méthode que d'appeler des ctors ou des dtors réels.
Vous devez définir un nom personnalisé pour les méthodes du trait Comme les méthodes de la classe écrase les méthodes du trait code> code> Vous devez affecter un nom différent aux méthodes du trait code>. Ensuite, vous pouvez appeler ces méthodes de votre classe.
Code>: p>
Ajout à Réponse AeremDir S: constructeurs hérités de la classe de base et de multiples traits ...
<?php trait T1 { public function __construct() { $this->someval |= 0b0001; echo "T1::__construct() done\n"; } } trait T2 { public function __construct() { $this->someval |= 0b0010; echo "T2::__construct() done\n"; } } class C1 { protected $someval; public function __construct() { $this->someval = 0b10000000; echo "C1::__construct() done\n"; } } class C2 extends C1 { use T1, T2 { T1::__construct as private T1__construct; T2::__construct as private T2__construct; } public function __construct() { parent::__construct(); $this->T1__construct(); $this->T2__construct(); $this->someval |= 0b00100000; echo "C2::__construct() done\n"; } public function someval() { $str = base_convert($this->someval, 10, 2); $len = strlen($str); if($len < 8) $str = str_repeat('0', 8 - $len) . $str; return '0b' . $str; } } $v1 = new C2(); echo $v1->someval(); ?>