Added ability to register callbacks for class instantiation.

pull/111/head v1.1.5
Mike Cao 11 years ago
parent 33c5fb794a
commit b9b2d0fa2d

@ -1 +1 @@
1.1.4 1.1.5

@ -40,12 +40,12 @@ class Loader {
* Registers a class. * Registers a class.
* *
* @param string $name Registry name * @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 array $params Class initialization parameters
* @param callback $callback Function to call after object instantiation * @param callback $callback Function to call after object instantiation
*/ */
public function register($name, $class, array $params = array(), $callback = null) { 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); $this->classes[$name] = array($class, $params, $callback);
} }
@ -67,50 +67,57 @@ class Loader {
* @return object Class instance * @return object Class instance
*/ */
public function load($name, $shared = true) { public function load($name, $shared = true) {
$obj = null;
if (isset($this->classes[$name])) { if (isset($this->classes[$name])) {
list($class, $params, $callback) = $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) ? if ($shared) {
$this->getInstance($class, $params) : $obj = ($exists) ?
$this->newInstance($class, $params); $this->getInstance($name) :
$this->newInstance($class, $params);
if ($do_callback) { if (!$exists) {
$this->instances[$name] = $obj;
}
}
else {
$obj = $this->newInstance($class, $params);
}
if ($callback && (!$shared || !$exists)) {
$ref = array(&$obj); $ref = array(&$obj);
call_user_func_array($callback, $ref); call_user_func_array($callback, $ref);
} }
return $obj;
} }
return ($shared) ? return $obj;
$this->getInstance($name) :
$this->newInstance($name);
} }
/** /**
* Gets a single instance of a class. * Gets a single instance of a class.
* *
* @param string $class Class name * @param string $name Instance name
* @param array $params Class initialization parameters * @return object Class instance
*/ */
public function getInstance($class, array $params = array()) { public function getInstance($name) {
if (!isset($this->instances[$class])) { return isset($this->instances[$name]) ? $this->instances[$name] : null;
$this->instances[$class] = $this->newInstance($class, $params);
}
return $this->instances[$class];
} }
/** /**
* Gets a new instance of a class. * 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 * @param array $params Class initialization parameters
* @return object Class instance * @return object Class instance
*/ */
public function newInstance($class, array $params = array()) { public function newInstance($class, array $params = array()) {
if (is_callable($class)) {
return call_user_func_array($class, $params);
}
switch (count($params)) { switch (count($params)) {
case 0: case 0:
return new $class(); return new $class();

@ -23,15 +23,15 @@ class AutoloadTest extends PHPUnit_Framework_TestCase
// Autoload a class // Autoload a class
function testAutoload(){ function testAutoload(){
$this->app->register('test', 'TestClass'); $this->app->register('user', 'User');
$loaders = spl_autoload_functions(); $loaders = spl_autoload_functions();
$test = $this->app->test(); $user = $this->app->user();
$this->assertTrue(sizeof($loaders) > 0); $this->assertTrue(sizeof($loaders) > 0);
$this->assertTrue(is_object($test)); $this->assertTrue(is_object($user));
$this->assertEquals('TestClass', get_class($test)); $this->assertEquals('User', get_class($user));
} }
// Check autoload failure // Check autoload failure

@ -40,14 +40,14 @@ class FlightTest extends PHPUnit_Framework_TestCase
function testRegister(){ function testRegister(){
Flight::path(__DIR__.'/classes'); Flight::path(__DIR__.'/classes');
Flight::register('test', 'TestClass'); Flight::register('user', 'User');
$test = Flight::test(); $user = Flight::user();
$loaders = spl_autoload_functions(); $loaders = spl_autoload_functions();
$this->assertTrue(sizeof($loaders) > 0); $this->assertTrue(sizeof($loaders) > 0);
$this->assertTrue(is_object($test)); $this->assertTrue(is_object($user));
$this->assertEquals('TestClass', get_class($test)); $this->assertEquals('User', get_class($user));
} }
// Map a function // Map a function

@ -7,6 +7,8 @@
*/ */
require_once 'PHPUnit/Autoload.php'; require_once 'PHPUnit/Autoload.php';
require_once __DIR__.'/classes/User.php';
require_once __DIR__.'/classes/Factory.php';
class LoaderTest extends PHPUnit_Framework_TestCase class LoaderTest extends PHPUnit_Framework_TestCase
{ {
@ -22,12 +24,12 @@ class LoaderTest extends PHPUnit_Framework_TestCase
// Autoload a class // Autoload a class
function testAutoload(){ function testAutoload(){
$this->loader->register('tests', 'TestClass'); $this->loader->register('tests', 'User');
$test = $this->loader->load('tests'); $test = $this->loader->load('tests');
$this->assertTrue(is_object($test)); $this->assertTrue(is_object($test));
$this->assertEquals('TestClass', get_class($test)); $this->assertEquals('User', get_class($test));
} }
// Register a class // Register a class
@ -76,4 +78,37 @@ class LoaderTest extends PHPUnit_Framework_TestCase
$this->assertTrue($user1 === $user2); $this->assertTrue($user1 === $user2);
$this->assertTrue($user1 !== $user3); $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));
}
} }

@ -8,6 +8,7 @@
require_once 'PHPUnit/Autoload.php'; require_once 'PHPUnit/Autoload.php';
require_once __DIR__.'/../flight/autoload.php'; require_once __DIR__.'/../flight/autoload.php';
require_once __DIR__.'/classes/User.php';
class RegisterTest extends PHPUnit_Framework_TestCase class RegisterTest extends PHPUnit_Framework_TestCase
{ {
@ -84,11 +85,3 @@ class RegisterTest extends PHPUnit_Framework_TestCase
$this->assertEquals(123, $user); $this->assertEquals(123, $user);
} }
} }
class User {
public $name;
public function User($name = ''){
$this->name = $name;
}
}

@ -0,0 +1,11 @@
<?php
class Factory {
// Cannot be instantiated
private function __construct() {
}
public static function create() {
return new self();
}
}

@ -1,8 +0,0 @@
<?php
class TestClass {
public $name;
public function TestClass($name = ''){
$this->name = $name;
}
}

@ -0,0 +1,8 @@
<?php
class User {
public $name;
public function User($name = ''){
$this->name = $name;
}
}
Loading…
Cancel
Save