php - 如何强制 Composer 脚本加载本地类而不是全局类
问题描述
未定义的方法
(相关文件链接在我的问题底部。)
我让 Composer 运行一些post-install-cmd
脚本post-update-cmd
。在我的脚本中,我想readlink()
使用symfony/filesystem
. 在我的项目/vendor
文件夹中有3.4
文件系统包的版本,很好。
我use Symfony\Component\Filesystem\Filesystem;
在我的文件的顶部。
但是每当我跑步时:
$fs = new Filesystem();
$path = '/path/to/some/symlink';
if ($fs->readlink($path)) {
// code
}
我收到以下错误,告诉我我正在调用未定义的方法:
PHP 致命错误:未捕获错误:调用 /Users/leymannx/Sites/blog/scripts/composer/ScriptHandler.php:160 中未定义的方法 Symfony\Component\Filesystem\Filesystem::readlink()
好的,所以我仔细检查了项目/vendor
文件夹中的类。这个方法是有的。我的 IDE 将我指向那里。但是当我运行时:
$fs = new Filesystem();
get_class_methods($fs);
此方法未列出。
它试图从哪个文件加载方法?
好的,所以我尝试检查它从哪个文件加载此类:
$fs = new Filesystem();
$a = new \ReflectionClass($fs);
echo $a->getFileName();
这让我回来了phar:///usr/local/Cellar/composer/1.7.2/bin/composer/vendor/symfony/filesystem/Filesystem.php
——但为什么呢?为什么它从我的 Mac 的酒窖中取出包裹?这很奇怪。
但是好的,所以我认为这是 Homebrew 问题,并卸载了 Homebrew Composer$ brew uninstall --force composer
并再次安装它作为 PHAR,如https://getcomposer.org/doc/00-intro.md#globally上记录的那样。
但现在是一样的。
$fs = new Filesystem();
$a = new \ReflectionClass($fs);
echo $a->getFileName();
返回我phar:///usr/local/bin/composer/vendor/symfony/filesystem/Filesystem.php
。
但为什么?为什么它会从我的全局 Composer 安装中获取(过时的)包?如何强制我的脚本使用项目的本地类,而不是全局 Composer 安装中的类?
还有什么?
最初我$PATH
包含/Users/leymannx/.composer/vendor/bin /usr/local/bin /usr/bin /bin /usr/sbin /sbin
. 我删除/Users/leymannx/.composer/vendor/bin
只返回/usr/local/bin /usr/bin /bin /usr/sbin /sbin
。还是一样。
我还尝试在我的composer.json
. 还是一样:
"optimize-autoloader": true,
"classmap-authoritative": true,
"vendor-dir": "vendor/",
我终于在 GitHub 上创建了一个问题:https ://github.com/composer/composer/issues/7708
解决方案
这是运行代码的上下文问题。如果您直接在其中执行某些方法,post-install-cmd
它将在 Composer 的进程内执行。这意味着它将共享捆绑在composer.phar
. 由于您不能有两个具有相同 FQN 的类,因此您不能Symfony\Component\Filesystem\Filesystem
在此上下文中包含另一个类。
您可以通过在单独的进程中运行脚本来绕过它。post-install-cmd.php
您可以在执行所有引导(如 require )的位置创建文件vendor/autoload.php
并调用这些方法。post-install-cmd
然后在你的钩子中运行这个文件:
"scripts": {
"post-install-cmd": [
"php post-install-cmd.php"
]
},
推荐阅读
- c# - 没有实体框架的 C# 中的存储库模式
- aws-lambda - 如果外部 json 状态发生变化,如何更改 AWS Step 函数的状态
- jquery - 悬停后向下滑动菜单,而不是单击
- python - 如何进行选择性介词标记nltk
- javascript - 用js验证输入
- python - 在其一列上应用 lambda 后如何保存数据框?
- sql - 多个查询导致出现次数最少
- shell - 通过后端配置 Controlm 作业?
- docker - 如何在支持 golang 的 gRPC 中减小 docker 镜像的大小?
- javascript - 部署 React-(Create-React-App)、Express.js 和 MySQL