如何强制Composer脚本加载本地类而不是全局类

时间:2018-10-11 13:49:25

标签: php symfony composer-php

未定义的方法

(相关文件链接在我的问题的底部。)

我让Composer运行一些post-install-cmdpost-update-cmd脚本。在我的脚本中,我想使用symfony/filesystem中的readlink()函数。在我的项目/vendor文件夹中,有3.4版的文件系统软件包,很好。

use Symfony\Component\Filesystem\Filesystem;位于文件顶部。

但是只要我跑步:

$fs = new Filesystem();
$path = '/path/to/some/symlink';
if ($fs->readlink($path)) {
  // code
}

我收到以下错误,告诉我我正在调用一个未定义的方法:

  

PHP致命错误:未捕获错误:调用未定义方法   中的Symfony \ Component \ Filesystem \ Filesystem :: readlink()   /Users/leymannx/Sites/blog/scripts/composer/ScriptHandler.php:160

好的,所以我仔细检查了项目/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,然后像https://getcomposer.org/doc/00-intro.md#globally中记录的那样,以PHAR的形式再次安装了它。

但是现在一样了。

$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


1 个答案:

答案 0 :(得分:1)

这与运行代码的上下文有关。如果您直接在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"
    ]
},