Overriding core classes with PHP
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:
- app
- core
- User.php (class User)
- custom
- User.php (class User)
- index.php (class Bootstrap with autoLoader)
- core
Now I want to check if “custom/User.php” exists and accordingly include and use this. It should extend the core User class.
My scripts looks like this at this moment:
core/User.php
<?php namespace Core; class User { public function getName() { return 'Pieter'; } }
custom/User.php
<?php namespace Custom; class User extends \Core\User { public function getName() { return 'Mr. '.parent::getName(); } }
index.php
<?php class Bootstrap { public function __construct() { spl_autoload_register(array('Bootstrap', 'autoLoader')); $user = new \Custom\User(); print_r($user->getName()); } private function autoLoader($className) { $fileName = str_replace("\\", "/", strtolower($className)).".php"; if (file_exists($fileName)) { require_once $fileName; } } } new Bootstrap();
The example above works fine, but when I delete the Custom\User class it stops working. This is correct behaviour because I’m trying to make an instance of the \Custom\User class which not exists. But what is the best way to change the autoloader to load the correct Core class?
I think there are 2 possibilities:
- Working with className variables. First check if the file exists and attach the correct namespace+classpath to the variable and keep working with that variable to load the class.
//I know the file_exists example won't work because of //the slashes but this is just an example $className = '\Custom\User.php'; if (!file_exists($className)) { $className = '\Core\User.php'; } $user = new $className();
- Create a static function like getService(‘User’) that handles all discussed matter above and returns the correct class.
public static function getService($classObj) { $className = '\Custom\\'.$classObj.'.php'; if (!file_exists($className)) { $className = '\Core\\'.$classObj.'.php'; } return new $className(); } $user = Register::getService('User');
I think the second option is the best one but is there some easier, more proper way to do this?
Thanks in advance.