我们如何重命名 composer 包命名空间?

How do we rename composer package namespaces?

提问人:Nero_Advents 提问时间:9/21/2023 最后编辑:Nero_Advents 更新时间:9/22/2023 访问量:49

问:

我在PrestaShop网站上有两个模块(myModuleA和myModuleB),它们使用不同版本的库phpoffice\phpspreadsheet。 问题是当我从 myModuleA 中的 phpoffice\phpspreadsheet 调用方法时,它开始使用 myModuleB phpoffice\phpspreadsheet 方法。

例:

Call to a member function setActiveSheetIndex() on null

in modules/mymoduleb/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/Worksheet.php (line 1439)

in modules/mymodulea/test.php (line 33).

是否可以从phpoffice\phpspreadsheet重命名命名空间?

我想像这样使用phpoffice\phpspreadsheet:

use MyModuleA\PhpOffice\PhpSpreadsheet\Spreadsheet; 

use MyModuleB\PhpOffice\PhpSpreadsheet\Spreadhsset; 
命名空间 composer-php prestashop phpoffice-phpspreadsheet

评论

0赞 Nico Haase 9/21/2023
他们如何使用不同的版本?您是否在该模块中使用了任何自定义命名空间?如果对两个版本使用相同的命名空间,则自动加载程序无法检测到存在两个不同的版本

答:

0赞 Samuel Cook 9/21/2023 #1

您无需重命名命名空间,只需使用别名:

use MyModuleA\PhpOffice\PhpSpreadsheet\Spreadsheet as module_a_spreadsheet;

use MyModuleB\PhpOffice\PhpSpreadsheet\Spreadsheet as module_b_spreadsheet;

然后,您可以独立使用它们:

module_a_spreadsheet::foo();

module_b_spreadsheet::foo();

有关别名的更多信息:https://www.php.net/manual/en/language.namespaces.importing.php


更新 - 根据您的注释,可以为整个命名空间创建别名,但您需要为原始类中调用的所有其他类注册相同的新命名空间别名。你可以使用 和 的组合,但在我看来,这似乎是对资源的巨大浪费,而且有点矫枉过正。我还没有测试下面的代码,但我认为这是一个很好的起点:spl_autoload_registerclass_alias

spl_autoload_register(
    function( $class_name ){
        
        $original_namespace = 'PhpOffice';

        if( substr($class_name,  0, strlen($original_namespace) ) != $original_namespace ) {
            return;
        }

        $module_a_class = 'MyModuleA\\'.$class_name;
        $module_b_class = 'MyModuleB\\'.$class_name;

        class_alias($module_a_class, $class_name);
        class_alias($module_b_class, $class_name);

        $module_a_exists = class_exists($module_a_class );
        $module_b_exists = class_exists($module_b_class );
    },
    $throw = true,
    $prepend = false
);

我认为最简单的解决方案是创建几个变量并使用这些变量:

$module_a_spreadsheet = new PhpOffice\PhpSpreadsheet\Spreadsheet();
$module_b_spreadsheet = new PhpOffice\PhpSpreadsheet\Spreadsheet();

评论

0赞 Nero_Advents 9/21/2023
您好,感谢您的回答。问题是我不知道如何在不重命名包中的每个文件的情况下将 MyModuleA\ 前缀添加到 phpoffice\phpspreadsheet 命名空间。实际上,我将其用作“使用PhpOffice\PhpSpreadsheet\Spreadsheet;”。
1赞 Krystian Podemski 9/22/2023 #2

这是PrestaShop模块的常见问题,我们没有一个composer.json,但所有模块都加载了它们的依赖项。

解决方案可能是为所有供应商添加前缀,有一些工具可以帮助您做到这一点:

https://github.com/humbug/php-scoper 或 PHP 前缀器:https://github.com/PHP-Prefixer/hello-prestashop-world