我开发了一个小型库,供公司内部和一些客户使用。该库是在 PHP 7 环境中开发的。
它已经在我同事的计算机上成功安装和使用,我的一些客户端服务器运行 PHP 7(包括 7.0 和 7.1)。最近,我在运行PHP 5.6的共享托管平台上遇到了一个客户端,作曲家可以下载并安装软件包而不会出现任何错误,但不会自动加载类,例如:
<?php
include "vendor/autoload.php";
use MyVendorMyPackageClientClientObject;
$client = new ClientObject();
// PHP 7 : OK
// PHP 5 : PHP Fatal Error: Cannot find class MyVendorMyPackageClient.....
在 PHP 7 环境中运行良好,但在 PHP 5 上不能运行。我以为它可能是共享主机,但我在我的机器上启动了一个 PHP 5 VM,并验证自动加载不起作用。
我检查了vendor/composer
目录,发现文件完全相同。自动加载仅对我的包失败,而不是它的依赖项(例如GuzzleHttp
),所以我的包可能有问题,但我不知道要注意什么。
我的软件包的附录目录结构,当由作曲家安装时:
- MyVendor
| - MyPackage
| | - src
| | | - client
| | | | - ClientObject.php
| | | - (other files and folders)
| | - composer.json
在 composer.json 中定义为"psr-4" : { "MyVendor\MyPackage\" : "src/" }
的自动加载器
回答我自己的问题:这不是PHP版本,而是不区分大小写的文件系统。
碰巧的是,"工作"的 PHP7 环境位于不区分大小写的文件系统上(NTFS、HFS+ 等),而 PHP5 环境则位于区分大小写的文件系统上,如 ext4。这包括通常具有区分大小写的文件系统(如 linux 文件系统)的系统上的共享/挂载文件夹,因此我敦促未来的读者对此格外小心。
如上所示,我的文件夹名称不符合 PSR4(必须完全匹配大小写),但这不会标记不区分大小写的文件系统上的任何问题,无论 PHP 版本如何。但是,如果您使用区分大小写的文件系统将项目部署到其他任何地方,它将中断。
因为您需要执行两次git mv
才能在不区分大小写的文件系统上大写文件夹名称(如下所示),因此如果您的项目已经有很多现有的子文件夹,则可能会变得乏味,因此我将保留此 bash 脚本,该脚本会自动执行此操作:(要点在这里)
#!/bin/bash
for i in `find src -type d | grep -v '^src$' | sort -r`; do
if [[ ! -e "$i"2 ]]; then
mkdir -p "$i"2
fi
echo "start"
for j in `find $i -maxdepth 1 -type f`; do
echo $(git mv "$j" "$i"'2')
done
i2=`echo $i | sed -e "s/b(.)/u1/g" | sed -e "s/Src/src/g"`
for j in `find $i'2' -maxdepth 1 -type f`; do
echo $(git mv "$j" "$i2")
done
done
for i in `find src -type d | grep -v '^src$'`; do
i2=`echo $i | sed -e "s/b(.)/u1/g" | sed -e "s/Src/src/g"`
rename $i $i2 $i
done
find . -type d -empty -name "*2" -delete