[eluser]Unknown[/eluser]
I'm just learning CI so I don't know if this is the best way to handle a singleton class but I extended the CI system/core/Loader class by creating application/core/MY_Loader which overrides the _ci_init_class method. The override _ci_init_class method uses the php reflectionClass to determine if the class has a 'getinstance' or 'get_instance' method (case-insensitive) and uses this method to instantiate. THIS IMPLEMENTATION REQUIRES PHP 5 >= 5.1.0. I suppose I could have re-written my class so it was not a singleton but that was work - and CI is supposed to make it easier :-). The only code changes from the core method occur below the comment "Instantiate the class" at the end.
file application/core/MY_Loader.php:
Code:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed') ;
/**
* MY_Loader Class
*
* Load classes including Singleton classes using a getInstance
* or get_instance method (case-insensitive) if it exists.
*
* @author Carl Anderson
*/
class MY_Loader extends CI_Loader
{
/**
* Instantiates a class
*
* @access private
* @param string
* @param string
* @param string an optional object name
* @return null
*/
function _ci_init_class($class, $prefix = '', $config = FALSE, $object_name = NULL)
{
// Is there an associated config file for this class? Note: these should always be lowercase
if ($config === NULL)
{
// Fetch the config paths containing any package paths
$config_component = $this->_ci_get_component('config');
if (is_array($config_component->_config_paths))
{
// Break on the first found file, thus package files
// are not overridden by default paths
foreach ($config_component->_config_paths as $path)
{
// We test for both uppercase and lowercase, for servers that
// are case-sensitive with regard to file names. Check for environment
// first, global next
if (defined('ENVIRONMENT') AND file_exists($path .'config/'.ENVIRONMENT.'/'.strtolower($class).EXT))
{
include_once($path .'config/'.ENVIRONMENT.'/'.strtolower($class).EXT);
break;
}
elseif (defined('ENVIRONMENT') AND file_exists($path .'config/'.ENVIRONMENT.'/'.ucfirst(strtolower($class)).EXT))
{
include_once($path .'config/'.ENVIRONMENT.'/'.ucfirst(strtolower($class)).EXT);
break;
}
elseif (file_exists($path .'config/'.strtolower($class).EXT))
{
include_once($path .'config/'.strtolower($class).EXT);
break;
}
elseif (file_exists($path .'config/'.ucfirst(strtolower($class)).EXT))
{
include_once($path .'config/'.ucfirst(strtolower($class)).EXT);
break;
}
}
}
}
if ($prefix == '')
{
if (class_exists('CI_'.$class))
{
$name = 'CI_'.$class;
}
elseif (class_exists(config_item('subclass_prefix').$class))
{
$name = config_item('subclass_prefix').$class;
}
else
{
$name = $class;
}
}
else
{
$name = $prefix.$class;
}
// Is the class name valid?
if ( ! class_exists($name))
{
log_message('error', "Non-existent class: ".$name);
show_error("Non-existent class: ".$class);
}
// Set the variable name we will assign the class to
// Was a custom class name supplied? If so we'll use it
$class = strtolower($class);
if (is_null($object_name))
{
$classvar = ( ! isset($this->_ci_varmap[$class])) ? $class : $this->_ci_varmap[$class];
}
else
{
$classvar = $object_name;
}
// Save the class name and object name
$this->_ci_classes[$class] = $classvar;
// Instantiate the class
$CI =& get_instance();
$rc = new ReflectionClass($name) ;
$gi = '' ;
$gi = $rc->hasMethod('getinstance')
? 'getinstance'
: ($rc->hasMethod('get_instance') ? 'get_instance' : '') ;
switch ( $gi )
{
case 'getinstance':
case 'get_instance':
if ($config !== NULL)
{
$CI->$classvar = $name::$gi($config) ;
}
else
{
$CI->$classvar = $name::$gi() ;
}
break ;
default:
if ($config !== NULL)
{
$CI->$classvar = new $name($config);
}
else
{
$CI->$classvar = new $name;
}
break ;
}
}
}
/* End of file MY_Loader.php */
/* Location: ./application/core/MY_Loader.php */