背景
这个sdk是一个历史项目了,后边做了composer化,拆分成了一个worker和一个composer包。再由worker引入composer包的形式继续使用。
很多个项目均引入了此sdk。
细节
目录结构
├─other_project │ main.php │ └─sdks │ sdk_link.php │ └─client sdk.php
使用方式
两个目录,other_project表示一个项目,此项目会引入sdk_link.php。而sdk_link.php实际上是软连接,连接的是sdks/client/sdk.php。
sdks是所有sdk的目录,一般的习惯都是把实际的sdk文件链接到根目录(项目组历史遗留陋习)。
问题
在sdk升级到composer的时候,由于要兼容历史使用方式(不带命名空间的类)。所以,在autoload中用files指定引入sdk.php文件(重点)。
"autoload":{ "psr-4": { "xx\\client\\": "client" }, "files": ["client/sdk.php"] }
在使用此sdk的项目中使用
require_once "sdks/sdk_link.php";
引入sdk进行使用。
此时报错:sdk.php文件中定义的类不能重复定义。
原因
虽说使用了require_once,但是composer生成的autoload用的是require(重点),导致重复加载了。
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { require $file; $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true; }
总结
使用require(require_once)引入composer化的项目中的文件时,一定要确保此文件没有在composer.json中通过files定义自动加载。
Ps:在无命名空间的项目中直接require composer项目一定要非常小心。。。
Ps:赶紧把项目升级到composer吧。。。。。。