Как заставить скрипт Composer загружать локальный класс вместо глобального класса - PullRequest
0 голосов
/ 11 октября 2018

неопределенный метод

(Соответствующие файлы указаны в нижней части моего вопроса.)

Я разрешаю Composer запускать некоторые сценарии post-install-cmd и post-update-cmd.В моем сценарии я хочу использовать функцию readlink() из symfony/filesystem.Внутри моей папки проектов /vendor находится версия пакета файловой системы 3.4, отлично.

I use Symfony\Component\Filesystem\Filesystem; вверху моего файла.

Но всякий раз, когда я запускаю:

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

Я получаю следующую ошибку, которая говорит мне, что я вызываю неопределенный метод:

Неустранимая ошибка PHP: Uncaught Ошибка: вызов неопределенного метода Symfony \ Component \ Filesystem \Файловая система :: readlink () в /Users/leymannx/Sites/blog/scripts/composer/ScriptHandler.php:160

OK, поэтому я дважды проверил класс в папке /vendor моего проекта,Этот метод есть.Моя IDE указывает на меня.Но когда я запускаю:

$fs = new Filesystem();
get_class_methods($fs);

, этот метод не указан.

Из какого файла он пытается загрузить метод?

OK, поэтому я попытался проверитьиз какого файла загружается этот класс:

$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's Cellar?Это странно.

Но хорошо, поэтому я подумал, что это проблема 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


1 Ответ

0 голосов
/ 12 октября 2018

Это контекст контекста, в котором выполняется ваш код.Если вы выполняете какой-либо метод непосредственно в 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"
    ]
},
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...