我遇到重新声明错误的问题。我还找不到它的解决办法,但基本上是:
或者有没有办法可以取消或清除功能?我尝试过include,require,require_once等......没有工作:(
答案 0 :(得分:7)
在PHP中,无法覆盖之前定义的函数。
因此模块以彼此的方式站立,一个模块阻止另一个模块工作。
实际上,模块需要使用相同的命名函数,而它们必须能够彼此并存。
可以通过将模块代码移动到自己的类中来完成。一个模块就是一个类。
然后,您可以使用模块类必须提供的功能定义接口。因此,模块必须具有简化的接口 - 例如,每个模块都有install()
和uninstall()
函数 - 只需在首先指定所需的模块函数时定义object interface:
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() {...}
}
这样做之后,只要你的一个例程需要处理任何模块,你就可以使该函数需要一个模块:
function module_install(Module $module) {
$module->install();
}
此功能仅接受现有模块作为参数。因此,您无法使用标准require / include,但模块需要在使用前进行实例化。您也可以将它放入模块加载器函数中:
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));
}
}
}
现在唯一剩下的就是访问实际的模块了。
您可以创建一个包含所有模块的全局数组变量:
// 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();
然而,这有一些问题。例如,所有模块都需要一次加载,但您可能不需要使用所有模块。或者想象你会覆盖全局$modules
数组,所有模块都会丢失。
为了防止所有这些并允许更多控制和更容易访问模块,可以将其放入自己的类中来处理所有细节。就像知道加载了哪些模块的寄存器一样,根据需要进行注册。
对于以下内容,我假设一个模块只能存在一次。如果一个对象只能存在一次,通常称为 Singleton 。因此,我们将包装加载管理并将模块的名称提供给它自己的类来处理细节:
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);
}
}
将此类放入module_definitions.php中,该类应始终包含在您的应用程序中。
因此,无论何时需要访问模块,您都可以使用带有模块名称的静态get函数来执行此操作:
Modules::get('Module1')->install();
Modules::get('Module2')->install();
答案 1 :(得分:2)
没有。您有应用程序设计问题。
重命名第二个函数,并在想要使用第二个函数的位置上调用它。
答案 2 :(得分:1)
在同一范围内,您不能拥有两个具有相同名称的功能。
如果您有php5.3或更高版本,名称空间可以是答案:每个插件都有自己的,所以函数变为
\plugin1\install()
\plugin2\install()
等等。
答案 3 :(得分:1)
您可能还希望在这些包含文件中创建唯一的类,然后让它们扩展泛型类,并将该泛型类用作要在更高级别调用这些函数时锚定的类型。你也可以让另一个重载,然后当你在一个方法中执行一个方法时,它可以直接传递给下一个方法。
答案 4 :(得分:0)
理论上如果你将每个文件的函数包装在一个单独的类中,那么你可以毫无问题地调用它们。如果静态调用它们,你甚至不需要真正担心类状态。
答案 5 :(得分:0)
您不能在同一名称空间中使用两次相同的函数名称。 您应该重命名第二个函数或使用“Maerlyn”建议
之类的命名空间答案 6 :(得分:0)
这个问题可以通过命名空间或/和静态类来解决 最简单的方法是使用静态方法将这些函数包装在类中 之后,您不仅可以同时包含它们,还可以使用autoload - 函数并忘记“包含”。
class Class1
{
public static function install()
{}
}
class Class2
{
public static function install()
{}
}