Page 3 of 3

Re: Event-driven programming

Posted: Tue Jan 11, 2011 5:07 am
by VladSun
Something like this?

Code: Select all

<?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');

Re: Event-driven programming

Posted: Tue Jan 11, 2011 6:20 am
by Benjamin
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.

Re: Event-driven programming

Posted: Thu Jan 13, 2011 4:55 am
by Benjamin
What are your thoughts on using the composite pattern for this?

http://devzone.zend.com/article/7

Re: Event-driven programming

Posted: Thu Jan 13, 2011 5:12 am
by josh
:-)


...

I think that's what me & Christopher said page 1 :-) :-)

Seriously though, buy the gang of four book. :-)

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!