Reputation: 92621
Scenario
The system has classes declared in /system/classes/
.
The application has classes declared in /application/classes/
.
If there is class in the application folder that has the same name as a class in the system folder then the class in the application folder should extend the class in the system folder.
Not all classes in the system folder will be overwritten by a class in the application folder.
Question
How can you cause the class in the system folder to extend the class in the application class only if there is a class in the application folder.
NB: All classes that can be overwritten are static classes
NB: Even if we have to name the application classes my_className it is fine, as long as we can still just call className::functionName()
I guess Im looking for something similar to how Code Igniter does it.
Example Class
The below class is used as a loader to load in all other classes (be they libraries, processes or other). It is also used to load in css/image/js files ect.
If the user was to extend the class they might want to add an ini()
function which would be used to load in ini
files.
class load {
protected static $helpers;
protected static $configs;
protected static $libraries;
protected static $processes;
protected static $js;
protected static $css;
public static function init() {
self::$helpers = new stdClass();
self::$libraries = new stdClass();
self::$configs = new stdClass();
self::$processes = new stdClass();
self::$css = new stdClass();
self::$js = new stdClass();
}
public static function config($name) {
if (isset(self::$configs->$name) && is_object(self::$configs->$name))
return self::$configs->$name;
if (is_file(CONFIG_DIR . $name . '.php')) {
require_once(CONFIG_DIR . $name . '.php');
self::$configs->$name = new $name();
return self::$configs->$name;
}
throw new exception('Could not load config file \'' . $name . '\'');
return false;
}
public static function helper($name) {
if (isset(self::$helpers->$name) && is_object(self::$helpers->$name))
return self::$helpers->$name;
if (is_file(APP_HELPER_DIR . $name . '.php')) {
require_once(APP_HELPER_DIR . $name . '.php');
self::$helpers->$name = new $name();
return self::$helpers->$name;
}
if (is_file(HELPER_DIR . $name . '.php')) {
require_once(HELPER_DIR . $name . '.php');
self::$helpers->$name = new $name();
return self::$helpers->$name;
}
throw new exception('Could not load helper file \'' . $name . '\'');
return false;
}
public static function library($name, $params = array()) {
if (empty($params) && isset(self::$libraries->$name) && is_object(self::$libraries->$name))
return self::$libraries->$name;
if (is_file(APP_LIBRARY_DIR . $name . '.php')) {
require_once(APP_LIBRARY_DIR . $name . '.php');
self::$libraries->$name = new $name($params);
return self::$libraries->$name;
}
if (is_file(LIBRARY_DIR . $name . '.php')) {
require_once(LIBRARY_DIR . $name . '.php');
self::$libraries->$name = new $name();
return self::$libraries->$name;
}
throw new exception('Could not load library file \'' . $name . '\'');
return false;
}
public static function process($name, $args = array()) {
if (isset(self::$processes->$name) && is_object(self::$processes->$name))
return self::$processes->$name;
if (is_file(PROCESS_DIR . $name . '.php')) {
require_once(PROCESS_DIR . $name . '.php');
if (empty($args)) {
self::$processes->$name = new $name();
return self::$processes->$name;
} else {
self::$processes->$name = new ReflectionClass($name);
return self::$processes->$name->newInstanceArgs($args);
}
}
throw new exception('Could not load process file \'' . $name . '\'');
return false;
}
public static function css($name) {
if (isset(self::$css->$name) && !empty(self::$css->$name))
return self::$css->$name;
self::$css->$name = '<link rel="stylesheet" type="text/css" href="' . CSS_PATH . $name . '.css">';
return self::$css->$name;
}
public static function js($name) {
if (isset(self::$js->$name))
return self::$js->$name;
self::$js->$name = '<script src="' . JS_PATH . $name . '.js"></script>';
return self::$js->$name;
}
public static function template($name, $vars = array()) {
if (is_file(TEMPLATE_DIR . $name . '.php')) {
ob_start();
if (!empty($vars))
extract($vars);
require(TEMPLATE_DIR . $name . '.php');
$contents = ob_get_contents();
ob_end_clean();
return $contents;
}
throw new exception('Could not load template file \'' . $name . '\'');
return false;
}
}
Upvotes: 1
Views: 135
Reputation: 11441
As far as I know code Igniter do replace classes, rather than extending them.
The more pratical way is to dinamically generate the code:
$code = file_get_contents($appFile);
if ( file_exists( $systemFile ) )
{
//don't do this ! Just a proof of concept, use regexp or code tokenizer
//you will also need to programmatically determine MyClass and SystemClass
$code = str_replace ('class myClass', 'class MyClass extends SystemClass', $code);
}
eval ($code)
Please note that eval is generally considered evil for good reasons, so be sure to double check your code. You may want to re-think your framework design instead.
UPDATE: if classes are just statical you may want to look into the Decorator pattern and __call() __get() __set(). That may suffice and avoid the eval() route.
Upvotes: 1