PHP包含2个使用相同函数名的文件会给出重新声明错误吗?

Mat*_*eid 3 php variables function include

我遇到了重新安装错误的麻烦.我找不到它的修复方法,但基本上:

  • 我有两个模块文件,它们使用相同的函数名称,如系统使用的install(),uninstall()等.
  • 当我同时包含两个文件以收集数据时,我得到重新声明错误.我想要它,以便我可以包括两个,当加载下一个文件时,它只是重写上一个函数.

或者有没有办法可以取消或清除功能?我试过include,require,require_once等...没有工作:(

hak*_*kre 7

在PHP中,无法覆盖先前定义的函数.

因此,模块以彼此的方式站立,一个模块阻止另一个模块工作.

实际上,模块需要使用相同的命名函数,而它们必须能够彼此并存.

这可以通过将模块代码移动到自己的类中来完成.一个模块就是一个类.

然后,您可以使用模块类必须提供的功能定义接口.因此,模块必须具有简化的接口 - 例如每个模块都有一个install()uninstall()函数 - 只需定义一个对象接口,首先指定所需的模块函数:

module_definitions.php

interface Module {
  public function install();
  public function uninstall();
}
Run Code Online (Sandbox Code Playgroud)

mod_Module1.php:

class Module1 implements Module {
  public function install() {...}
  public function uninstall() {...}
}
Run Code Online (Sandbox Code Playgroud)

mod_Module2.php:

class Module2 implements Module {
  public function install() {...}
  public function uninstall() {...}
}
Run Code Online (Sandbox Code Playgroud)

在这样做之后,只要你的一个例程需要处理任何模块,你就可以使该函数需要一个模块:

function module_install(Module $module) {
  $module->install();
}
Run Code Online (Sandbox Code Playgroud)

此函数仅接受现有模块作为参数.因此,您无法使用标准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));
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

那么如何访问模块功能呢?

现在唯一剩下的就是访问实际的模块了.

您可以创建一个包含所有模块的全局数组变量:

// 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();
Run Code Online (Sandbox Code Playgroud)

然而,这有一些问题.例如,所有模块都需要一次加载,但您可能不需要使用所有模块.或者想象你会覆盖全局$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);
  }
}
Run Code Online (Sandbox Code Playgroud)

将此类放入module_definitions.php中,该类应始终包含在您的应用程序中.

因此,无论何时需要访问模块,您都可以使用带有模块名称的静态get函数:

Modules::get('Module1')->install();
Modules::get('Module2')->install();
Run Code Online (Sandbox Code Playgroud)