Can we inject some more lines in a function by extending it with PHP? -
i have idea event system i'm developing custom framework.
imagine pseudo function this.
class test { public function hi() { event::add(__function__ . 'is run.'); return "hi"; } }
imagine need same more functions. (maybe want log functions ran @ runtime , want log them in separate file.)
instead of doing , adding events functions manually, can this?
class test { public function hi() { return "hi"; } } // events.php (it's pseudo code may not work.) // imagine extend's purpose inject codes target function event::bind('on', $classname, $methodname, function() use ($classname, $methodname) { return $classname->$methodname->extend('before', event::add(__function__ . 'is run.')); });
the idea inject hi()
function inside test class
, injecting whatever pass in extend
function outside. 'before'
means injection has @ first line of target function.
finally, events , event bindings kept abstracted away functions. want able bind custom things without altering functions.
i have feeling can hacking around eval()
or toying call_user_func()
. i'm not sure, though. using eval()
sounds pretty bad already.
my question is;
- is possible thing php?
- does has name in oop/oop principles can read further?
- does make sense or bad idea?
yes, can. can use aop using go-aop-php libriary works on annotations.
for example want log every public method calling. instead of adding every function line this.
namespace acme; class controller { public function updatedata($arg1, $arg2) { $this->logger->info("executing method " . __method__, func_get_args()); // ... } }
you can use one aspect public methods of classes of acme namespace this:
use go\aop\aspect; use go\aop\intercept\methodinvocation; use go\lang\annotation\before; class loggingaspect implements aspect { /** @var null|loggerinterface */ protected $logger = null; /** ... */ public function __construct($logger) { $this->logger = $logger; } /** * method should called before real method * * @param methodinvocation $invocation invocation * @before("execution(public acme\*->*())") */ public function beforemethodexecution(methodinvocation $invocation) { $obj = $invocation->getthis(); $class = is_object($obj) ? get_class($obj) : $obj; $type = $invocation->getmethod()->isstatic() ? '::' : '->'; $name = $invocation->getmethod()->getname(); $method = $class . $type . $name; $this->logger->info("executing method " . $method, $invocation->getarguments()); } }
it looks more complicated it's more flexible.
Comments
Post a Comment