Php 将所需类定义的范围限制为函数

Php 将所需类定义的范围限制为函数,php,plugins,php-include,Php,Plugins,Php Include,我有很多插件的文件夹。每个插件包含相同的名称类,但内容不同: plugin01.php plugin02.php 在Plugins.php中,我想加载这个插件。但不止一次 class Plugins{ public static function load($id){ require $id.'.php'; $plugin = new Plugin(); return $plugin->get('test'); } } echo Plugins:

我有很多插件的文件夹。每个插件包含相同的名称类,但内容不同:

plugin01.php

plugin02.php

在Plugins.php中,我想加载这个插件。但不止一次

class Plugins{
  public static function load($id){
    require $id.'.php';
    
    $plugin = new Plugin();
    return $plugin->get('test');
  }
}

echo Plugins::load('plugin01')."\n";
echo Plugins::load('plugin02')."\n";
echo Plugins::load('plugin01');
预期结果:

插件01-测试

插件02-测试

插件01-测试

当前结果:

致命错误:无法重新声明类插件

这肯定行不通,因为我正在重新定义类名,并多次包含同一个插件

我的问题是,我是否可以只在函数范围中包含文件,包括在外部文件中定义的所有类,若这些类不会出现在函数之外

我可以用PHP实现这一点,还是必须为每个类使用不同的名称?

手册:

包含文件时,它包含的代码将继承包含文件所在行的变量范围。从该点开始,调用文件中该行可用的任何变量都将在被调用文件中可用。但是,包含文件中定义的所有函数和类都具有全局作用域


因此,您应该重命名您的类,因为它的作用域是全局的。

如果您一次只能加载一个插件,那么您的方法就可以工作了。但正如您所发现的,它将与具有相同名称的多个类断开

我认为更好的解决方案是使用,然后让不同的插件实现这些接口

因此,定义一个包含插件应具有的所有方法的接口:

interface Plugin
{
    public function get($a);
}
然后让每个插件实现它:

// Plugin1.php
class Plugin1 implements Plugin
{
    public function get($a)
    {
        return 'Plugin 1 ' . $a;
    }
}
然后您可以用几乎相同的方式加载和实例化它们:

class Plugins{
  public static function load($pluginName){
    require_once( $pluginName.'.php');

    $plugin = new $pluginName();
    return $plugin;
  }
}

$plugin1 = Plugins::load('Plugin1');
echo $plugin1->get('Test');
$plugin2 = Plugins::load('Plugin2');
echo $plugin2->get('Test');

事实上,这个问题与包含本身无关。在php中,非名称空间的函数和类始终是全局的。是的,根据他拥有的php版本,他可以使用名称空间。在php中,取消类的定义也是不可能的。主要问题是,可能有500多个插件。可能会有重复的名称。通常你有一个命名约定并坚持它,例如:+1看起来不错,但它并不能解决我的问题。在这种情况下,muss我也关心插件的唯一名称,这在有500个插件的外部开发人员时很难做到。@m1k10您可以尝试使用名称空间。好吧,这不是我所期望的,我也必须关心uniq名称空间,但似乎用PHP无法做到这一点。
// Plugin1.php
class Plugin1 implements Plugin
{
    public function get($a)
    {
        return 'Plugin 1 ' . $a;
    }
}
// Plugin2.php
class Plugin2 implements Plugin
{
    public function get($a)
    {
        return 'Plugin 2 ' . $a;
    }
}
class Plugins{
  public static function load($pluginName){
    require_once( $pluginName.'.php');

    $plugin = new $pluginName();
    return $plugin;
  }
}

$plugin1 = Plugins::load('Plugin1');
echo $plugin1->get('Test');
$plugin2 = Plugins::load('Plugin2');
echo $plugin2->get('Test');