note 129816 added to language.oop5.magic
| From: | roemer@lievaart.net | Date: | Thu, 24 Oct 2024 11:18:19 +0000 |
| Subject: | note 129816 added to language.oop5.magic | ||
| Groups: | php.notes | ||
| Request: | Send a blank email to php-notes+get-221607@lists.php.net to get a copy of this message | ||
If you're like me, you like to expand PHP's capabilities. Then sometimes you find yourself
make traits with magic methods, simply because it's the only way (even though not recommended).
If you ever find yourself in that situation, you need to realize that you cannot reference the magic
method in a trait like you can with inheritance.
<?php
class myClass {
use traitA;
function __get($name) {
traitA::__get($name) ; // Doesn't work, error
parent::__get($name) ; // Doesn't work: a trait is not a parent, error (or
worse)
}
}
?>
The way to deal with that or even two traits with the same magic method (again, normally you
shouldn't end up there, but in special occasions, it does happen), the only way I found to
handle those is by defining the functionality of the magic method separately in a method. Like such:
<?php
trait traitA {
function __get($name) {
if ( $rtn = $this->__getTraitA($name) ) return $rtn;
else ... // error handling
}
function __getTraitA($name) {
if ( $allOk) return $stuff;
else return null;
}
}
?>
This works if there are no other __get magic methods. However as soon as you want a __get() in the
class itself the __get in the trait gets overwritten. So you will have to do:
<?php
class myClass {
use traitA;
function __get($name) {
// Code to execute before attempting __getTraitA
if ( $rtn = $this->__getTraitA($name) ) return $rtn;
// Optional additional code after __getTraitA
// Error handling code if no value is returned
}
}
?>
You can even have two traits with __get which would normally result in an error, if you build a
__get in the class as well:
<?php
class myClass {
use traitA, traitB;
function __get(string $propName) {
$r = $this->__getTraitA($propName) ?: $this->__getTraitB($propName);
if ($r) return $r;
//error handling
}
}
?>
The __get here overwrites both __get's in the traits, so the error is gone. This way the traits
work in any case and any combination of classes and traits.
----
Server IP: 45.112.84.4
Probable Submitter: 80.90.5.137 (proxied: 85.145.75.206)
----
Manual Page -- https://php.net/manual/en/language.oop5.magic.php
Edit -- https://main.php.net/note/edit/129816
Del: integrated -- https://main.php.net/note/delete/129816/integrated
Del: useless -- https://main.php.net/note/delete/129816/useless
Del: bad code -- https://main.php.net/note/delete/129816/bad+code
Del: spam -- https://main.php.net/note/delete/129816/spam
Del: non-english -- https://main.php.net/note/delete/129816/non-english
Del: in docs -- https://main.php.net/note/delete/129816/in+docs
Del: other reasons-- https://main.php.net/note/delete/129816
Reject -- https://main.php.net/note/reject/129816
Search -- https://main.php.net/manage/user-notes.php