i'm having trouble with a redeclare error. I can't find a fix for it yet, but basically:
Or is there a way I can unset or clear the function? I've tried include, require, require_once etc... No work :(
In PHP it is not possible to overwrite a function that you have previously defined.
So the modules stand in each others way and one module prevents the other from working.
Actually Modules need to make use of the same named functions while they must be able to co-exist next to each other.
That can be done by moving the modules code into classes of their own. One module is one class then.
You can then define an interface with the functions your module classes must provide. As Modules therefore must have a streamlined interface - each module has a install() and uninstall() function for example - just define an object interface at first specifying those needed module functions:
module_definitions.php
interface Module {
public function install();
public function uninstall();
}
mod_Module1.php:
class Module1 implements Module {
public function install() {...}
public function uninstall() {...}
}
mod_Module2.php:
class Module2 implements Module {
public function install() {...}
public function uninstall() {...}
}
After doing so, whenever one of your routines needs to deal with any module, you can make that function require a module:
function module_install(Module $module) {
$module->install();
}
This function will only accept an existing module as a parameter. So you can not use your standard require/include for this but modules need to be instantiated prior use. You can put that into a module loader function as well:
function module_require($moduleName) {
$class = $moduleName;
if (!class_exists($class) {
$file = sprintf('mod_%s.php', $moduleName);
require $file;
if (!class_exists($class)) {
throw new DomainException(sprintf('Invalid Module File %s for Module %s.', $file, $moduleName));
}
}
}
The only thing left is now to access the actual module.
You could the create a global array variable containing all modules:
// Define existing modules
$modules = array('Module1', 'Module2');
// Require the modules
array_map('module_require', $modules);
// instantiate each module:
$moduleInstances = array_map(function($module){return new $module;}, $modules);
// map modules name (key) to it's module instance:
$modules = array_combine($modules, $moduleInstances);
// access module by name:
$modules['Module1]->install();
However this has some problems. All modules need to be loaded at once for example, but you might not need to use all modules. Or imagine you would overwrite the global $modules array, all modules would be lost.
To prevent all that and allow more control and easier access to the modules, this can be put into a class of it's own that will take care of all the details. Like a register that knows which modules are loaded or not, registers them as needed.
For the following I assume a module can only exists once. If an object can only exist once this is often called a Singleton. So we'll wrap the management of loading and providing the module by it's name into a class of it's own that deals with the details:
class Modules {
private $modules = array();
private static $instance;
// singleton implementation for Modules manager
private static function getInstance() {
if (null === Modules::$instance) {
Modules::$instance = new Modules;
}
return Modules::$instance;
}
// singleton-like implementation for each Module
public function get($moduleName) {
if (!isset($this->modules[$moduleName]) {
module_require($moduleName);
$newModule = new $moduleName();
if (! $newModule instanceof Module) {
throw new DomainException(sprintf('Not a Module: %s', $moduleName));
}
$this->modules[$moduleName] = $newModule;
}
return $this->modules[$moduleName];
}
// get a module by name
public static function get($moduleName) {
return Modules::getInstance()->get($moduleName);
}
}
Put this class into module_definitions.php as well, which should be always included in your application.
So whenever you need to access a module you can do now by using the static get function with the name of the module:
Modules::get('Module1')->install();
Modules::get('Module2')->install();
No. You have a application design problem.
Rename the second function and call it on the locations you want the second to be used.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With