我在 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;
您不需要重命名命名空间,只需使用别名即可:
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_register
和 class_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();
这是 PrestaShop 模块的一个常见问题,我们没有一个composer.json,但所有模块都会加载其依赖项。
解决方案可能是为所有供应商添加前缀,有一些工具可以帮助您做到这一点:
https://github.com/humbug/php-scoper 或 PHP 前缀:https://github.com/PHP-Prefixer/hello-prestashop-world