Reputation: 4583
No idea if it's possible what I want, but I'm working on an application that requires custom classes to override the core functionality, if these files exist.
So as an example, this is my current file structure (simplified, without 'customer_slug')
Now I want to check if "custom/User.php" exists and accordingly include and use this. It should extend the core (abstract) User class.
My "entry" script looks like this at the moment:
<?php
function __autoload($class_name) {
$dispatch = Dispatcher::getInstance();
$dispatch->get($class_name);
}
class Dispatcher {
private static $instance;
private static $customer_slug = 'sony';
private function __clone() {
// Empty magic function to prevent cloning
}
private function __construct() {
// Empty magic function to prevent initialization
}
public static function getInstance()
{
if (!isset(self::$instance)) {
$class = __CLASS__;
self::$instance = new $class;
}
return self::$instance;
}
public static function get($class) {
// Autoload class
$basepath = $class.'.php';
// Include bas class
include('core/'.$basepath);
// Do we have custom functionality
if (file_exists('custom/'.self::$customer_slug.'/'.$basepath)) {
include('custom/'.self::$customer_slug.'/'.$basepath);
}
}
}
$User = new User;
print_r($User);
?>
I've tried fiddling with Namespaces, but can't really seem to get it working. I would like to keep saying "$user = new User;". No idea how else I'd call the class, perhaps $user = new $custom_or_code_classname
So I'm open to other approaches as well. Maybe a hook system?
Upvotes: 2
Views: 899
Reputation: 21
We implemented a solution to this using the __autoload(). Basically you have 2 variables, one for "app" and one for "client". Then you structure your classes in directories that match. e.g.
classes/app1/User.php
classes/app2/User.php
classes/app1/client1/User.php
etc
Then in the autoload fxn you build an array of possible paths. assuming app1, client1, array would be:
$paths = array('classes/app1/client1/User.php', 'classes/app1/User.php', 'classes/User.php');
Then iterate through looking for file_exists() and calling require_once().
All of the classes themselves should be named based on where they live:
class User__client1__app1 extends User__client1
class User__client1 extends User__base
class User__base
So the tricky part here is effectively aliasing the proper one to the root name (User).
In the autoloader, after you've found the proper class, do:
eval("class User extends $found_class { }");
Upvotes: 2