Not for 'how-to' coding questions but PHP theory instead, this forum is here for those of us who wish to learn about design aspects of programming with PHP.
<?php
class AOPizer
{
protected $object = null;
protected $beforeCallbacks = array();
protected $afterCallbacks = array();
public function __construct($object)
{
$this->object = $object;
}
public function __call($method, $args)
{
if (isset($this->beforeCallbacks[$method]))
foreach ($this->beforeCallbacks[$method] as $callback)
call_user_func_array($callback, array_merge(array($method), $args));
$result = call_user_func_array(array($this->object, $method), $args);
if (isset($this->afterCallbacks[$method]))
foreach ($this->afterCallbacks[$method] as $callback)
call_user_func_array($callback, array_merge(array($method), $args));
return $result;
}
public function before($method, $callback)
{
if (!isset($this->beforeCallbacks[$method]))
$this->beforeCallbacks[$method] = array();
$this->beforeCallbacks[$method][] = $callback;
}
public function after($method, $callback)
{
if (!isset($this->afterCallbacks[$method]))
$this->afterCallbacks[$method] = array();
$this->afterCallbacks[$method][] = $callback;
}
}
class User
{
public function save($username)
{
echo "User::save";
}
}
class Logger
{
public function log($method, $data)
{
echo "Logger::log ($method)";
}
public function getCallback()
{
return array($this, 'log');
}
}
$logger = new Logger();
$user = new AOPizer(new User());
$user->before('save', $logger->getCallback());
$user->after('save', $logger->getCallback());
$user->save('VladSun');
There are 10 types of people in this world, those who understand binary and those who don't
Hey Vladsun, thanks for chimming in. You're approach is really cool and pretty ingenious. I actually meant writing an actual module for the PHP engine itself.
There's a few things that bug me about it though:
1. It's like a reverse wrapper in that you are sending objects and intercept commands to a class.
2. I don't know how well it would work with nesting.
3. You have to create instances of every class that might ever be used.
I think at the end of the day the only way to truly implement AOP in an elegant way is for it to be supported by the programming language itself.
PS > I think I called it components, but "componentization" is basically synonymous with that pattern, my apologies for not using the 100% accurate pattern name. (for example control+f and search "components" that is the word that dominates the page. My apologies for calling it that instead of it's actual pattern name. Bad pattern name in my opinion)
josh wrote:The biggest I would say is component based re-use instead of inheritance based re-use.
Note that this is half the beauty to unit testing. The composition pattern!