From b9b2d0fa2d75e6b2f606fbd0d9a8059a0f741578 Mon Sep 17 00:00:00 2001 From: Mike Cao Date: Tue, 18 Mar 2014 20:48:33 -0700 Subject: [PATCH] Added ability to register callbacks for class instantiation. --- VERSION | 2 +- flight/core/Loader.php | 49 +++++++++++++++++++++---------------- tests/AutoloadTest.php | 8 +++--- tests/FlightTest.php | 8 +++--- tests/LoaderTest.php | 39 +++++++++++++++++++++++++++-- tests/RegisterTest.php | 9 +------ tests/classes/Factory.php | 11 +++++++++ tests/classes/TestClass.php | 8 ------ tests/classes/User.php | 8 ++++++ 9 files changed, 94 insertions(+), 48 deletions(-) create mode 100644 tests/classes/Factory.php delete mode 100644 tests/classes/TestClass.php create mode 100644 tests/classes/User.php diff --git a/VERSION b/VERSION index 65087b4..e25d8d9 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.1.4 +1.1.5 diff --git a/flight/core/Loader.php b/flight/core/Loader.php index de50532..f216f06 100644 --- a/flight/core/Loader.php +++ b/flight/core/Loader.php @@ -40,12 +40,12 @@ class Loader { * Registers a class. * * @param string $name Registry name - * @param string $class Class name + * @param string|callable $class Class name or function to instantiate class * @param array $params Class initialization parameters * @param callback $callback Function to call after object instantiation */ public function register($name, $class, array $params = array(), $callback = null) { - unset($this->instances[$class]); + unset($this->instances[$name]); $this->classes[$name] = array($class, $params, $callback); } @@ -67,50 +67,57 @@ class Loader { * @return object Class instance */ public function load($name, $shared = true) { + $obj = null; + if (isset($this->classes[$name])) { list($class, $params, $callback) = $this->classes[$name]; - $do_callback = ($callback && (!$shared || !isset($this->instances[$class]))); + $exists = isset($this->instances[$name]); - $obj = ($shared) ? - $this->getInstance($class, $params) : - $this->newInstance($class, $params); + if ($shared) { + $obj = ($exists) ? + $this->getInstance($name) : + $this->newInstance($class, $params); + + if (!$exists) { + $this->instances[$name] = $obj; + } + } + else { + $obj = $this->newInstance($class, $params); + } - if ($do_callback) { + if ($callback && (!$shared || !$exists)) { $ref = array(&$obj); call_user_func_array($callback, $ref); } - - return $obj; } - return ($shared) ? - $this->getInstance($name) : - $this->newInstance($name); + return $obj; } /** * Gets a single instance of a class. * - * @param string $class Class name - * @param array $params Class initialization parameters + * @param string $name Instance name + * @return object Class instance */ - public function getInstance($class, array $params = array()) { - if (!isset($this->instances[$class])) { - $this->instances[$class] = $this->newInstance($class, $params); - } - - return $this->instances[$class]; + public function getInstance($name) { + return isset($this->instances[$name]) ? $this->instances[$name] : null; } /** * Gets a new instance of a class. * - * @param string $class Class name + * @param string|callable $class Class name or callback function to instantiate class * @param array $params Class initialization parameters * @return object Class instance */ public function newInstance($class, array $params = array()) { + if (is_callable($class)) { + return call_user_func_array($class, $params); + } + switch (count($params)) { case 0: return new $class(); diff --git a/tests/AutoloadTest.php b/tests/AutoloadTest.php index 7aab378..3fef4da 100644 --- a/tests/AutoloadTest.php +++ b/tests/AutoloadTest.php @@ -23,15 +23,15 @@ class AutoloadTest extends PHPUnit_Framework_TestCase // Autoload a class function testAutoload(){ - $this->app->register('test', 'TestClass'); + $this->app->register('user', 'User'); $loaders = spl_autoload_functions(); - $test = $this->app->test(); + $user = $this->app->user(); $this->assertTrue(sizeof($loaders) > 0); - $this->assertTrue(is_object($test)); - $this->assertEquals('TestClass', get_class($test)); + $this->assertTrue(is_object($user)); + $this->assertEquals('User', get_class($user)); } // Check autoload failure diff --git a/tests/FlightTest.php b/tests/FlightTest.php index eaaee33..70ed453 100644 --- a/tests/FlightTest.php +++ b/tests/FlightTest.php @@ -40,14 +40,14 @@ class FlightTest extends PHPUnit_Framework_TestCase function testRegister(){ Flight::path(__DIR__.'/classes'); - Flight::register('test', 'TestClass'); - $test = Flight::test(); + Flight::register('user', 'User'); + $user = Flight::user(); $loaders = spl_autoload_functions(); $this->assertTrue(sizeof($loaders) > 0); - $this->assertTrue(is_object($test)); - $this->assertEquals('TestClass', get_class($test)); + $this->assertTrue(is_object($user)); + $this->assertEquals('User', get_class($user)); } // Map a function diff --git a/tests/LoaderTest.php b/tests/LoaderTest.php index 65d61f5..00219d4 100644 --- a/tests/LoaderTest.php +++ b/tests/LoaderTest.php @@ -7,6 +7,8 @@ */ require_once 'PHPUnit/Autoload.php'; +require_once __DIR__.'/classes/User.php'; +require_once __DIR__.'/classes/Factory.php'; class LoaderTest extends PHPUnit_Framework_TestCase { @@ -22,12 +24,12 @@ class LoaderTest extends PHPUnit_Framework_TestCase // Autoload a class function testAutoload(){ - $this->loader->register('tests', 'TestClass'); + $this->loader->register('tests', 'User'); $test = $this->loader->load('tests'); $this->assertTrue(is_object($test)); - $this->assertEquals('TestClass', get_class($test)); + $this->assertEquals('User', get_class($test)); } // Register a class @@ -76,4 +78,37 @@ class LoaderTest extends PHPUnit_Framework_TestCase $this->assertTrue($user1 === $user2); $this->assertTrue($user1 !== $user3); } + + // Gets an object from a factory method + function testRegisterUsingCallable(){ + $this->loader->register('e', array('Factory','create')); + + $obj = $this->loader->load('e'); + + $this->assertTrue(is_object($obj)); + $this->assertEquals('Factory', get_class($obj)); + + $obj2 = $this->loader->load('e'); + + $this->assertTrue(is_object($obj2)); + $this->assertEquals('Factory', get_class($obj2)); + $this->assertTrue($obj === $obj2); + + $obj3 = $this->loader->load('e', false); + $this->assertTrue(is_object($obj3)); + $this->assertEquals('Factory', get_class($obj3)); + $this->assertTrue($obj !== $obj3); + } + + // Gets an object from a callback function + function testRegisterUsingCallback(){ + $this->loader->register('f', function(){ + return Factory::create(); + }); + + $obj = $this->loader->load('f'); + + $this->assertTrue(is_object($obj)); + $this->assertEquals('Factory', get_class($obj)); + } } diff --git a/tests/RegisterTest.php b/tests/RegisterTest.php index 9b05e5f..bc57414 100644 --- a/tests/RegisterTest.php +++ b/tests/RegisterTest.php @@ -8,6 +8,7 @@ require_once 'PHPUnit/Autoload.php'; require_once __DIR__.'/../flight/autoload.php'; +require_once __DIR__.'/classes/User.php'; class RegisterTest extends PHPUnit_Framework_TestCase { @@ -83,12 +84,4 @@ class RegisterTest extends PHPUnit_Framework_TestCase $this->assertEquals(123, $user); } -} - -class User { - public $name; - - public function User($name = ''){ - $this->name = $name; - } } \ No newline at end of file diff --git a/tests/classes/Factory.php b/tests/classes/Factory.php new file mode 100644 index 0000000..1136d22 --- /dev/null +++ b/tests/classes/Factory.php @@ -0,0 +1,11 @@ +name = $name; - } -} \ No newline at end of file diff --git a/tests/classes/User.php b/tests/classes/User.php new file mode 100644 index 0000000..dba3898 --- /dev/null +++ b/tests/classes/User.php @@ -0,0 +1,8 @@ +name = $name; + } +} \ No newline at end of file