0 added
0 removed
Original
2026-01-01
Modified
2026-02-26
1
<p>Многие пакеты - это приложения командной строки, еще их называют<a>cli-утилитами</a>. Пользователи по-разному взаимодействуют с ними: запускают команды, передают аргументы и опции, выводят результат. Все взаимодействие происходит интерактивным образом через терминал. Для запуска файлов из командной строки в Composer существует секция bin конфигурационного файла composer.json. Рассмотрим на примере:</p>
1
<p>Многие пакеты - это приложения командной строки, еще их называют<a>cli-утилитами</a>. Пользователи по-разному взаимодействуют с ними: запускают команды, передают аргументы и опции, выводят результат. Все взаимодействие происходит интерактивным образом через терминал. Для запуска файлов из командной строки в Composer существует секция bin конфигурационного файла composer.json. Рассмотрим на примере:</p>
2
<p>Эта запись означает, что при установке пакета в операционной системе будет создан файл с именем php-package. Это не просто файл, а<a>символическая ссылка</a>. Запуск этого файла-ссылки приведет к запуску файла вашего проекта по адресу bin/php-package.</p>
2
<p>Эта запись означает, что при установке пакета в операционной системе будет создан файл с именем php-package. Это не просто файл, а<a>символическая ссылка</a>. Запуск этого файла-ссылки приведет к запуску файла вашего проекта по адресу bin/php-package.</p>
3
<p>Как можно заметить, имя ссылки задается именем файла и совпадает с ним. Также обратите внимание, что ссылок может быть множество - столько, сколько вы сами укажете в секции bin.</p>
3
<p>Как можно заметить, имя ссылки задается именем файла и совпадает с ним. Также обратите внимание, что ссылок может быть множество - столько, сколько вы сами укажете в секции bin.</p>
4
<p>Месторасположение символической ссылки и способ ее запуска из командной строки различаются в зависимости от способа установки пакета:</p>
4
<p>Месторасположение символической ссылки и способ ее запуска из командной строки различаются в зависимости от способа установки пакета:</p>
5
<ul><li>Локального</li>
5
<ul><li>Локального</li>
6
<li>Глобального с командой global - например, composer global vendor/package</li>
6
<li>Глобального с командой global - например, composer global vendor/package</li>
7
</ul><p>Рассмотрим каждый случай отдельно.</p>
7
</ul><p>Рассмотрим каждый случай отдельно.</p>
8
<h2>Глобальная установка: генерация ссылок и запуск исполняемых файлов</h2>
8
<h2>Глобальная установка: генерация ссылок и запуск исполняемых файлов</h2>
9
<p>При глобальной установке пакета Composer создает символические ссылки в каталоге $HOME/.composer/vendor/bin. Другими словами, при создании ссылок в домашнюю директорию пользователя, от имени которого запускалась установка пакета, будет добавлен каталог .composer/vendor/bin со ссылками. Это каталог по умолчанию, но путь к нему нам надо<a>самостоятельно прописать</a>в переменной окружения PATH. После этого мы можем запускать приложение по имени символической ссылки из командной строки, находясь в любой точке файловой системы. Так происходит, потому что при поиске исполняемых файлов командная оболочка ищет их последовательно по всем путям, прописанным в переменной окружения PATH.</p>
9
<p>При глобальной установке пакета Composer создает символические ссылки в каталоге $HOME/.composer/vendor/bin. Другими словами, при создании ссылок в домашнюю директорию пользователя, от имени которого запускалась установка пакета, будет добавлен каталог .composer/vendor/bin со ссылками. Это каталог по умолчанию, но путь к нему нам надо<a>самостоятельно прописать</a>в переменной окружения PATH. После этого мы можем запускать приложение по имени символической ссылки из командной строки, находясь в любой точке файловой системы. Так происходит, потому что при поиске исполняемых файлов командная оболочка ищет их последовательно по всем путям, прописанным в переменной окружения PATH.</p>
10
<p>В зависимости от версии Composer директория по умолчанию может различаться. Кроме того, это значение можно<a>конфигурировать</a>. Чтобы посмотреть, в какую конкретно директорию<strong>composer</strong>складывает ссылки на исполняемые файлы, можно воспользоваться командой composer global config bin-dir --absolute:</p>
10
<p>В зависимости от версии Composer директория по умолчанию может различаться. Кроме того, это значение можно<a>конфигурировать</a>. Чтобы посмотреть, в какую конкретно директорию<strong>composer</strong>складывает ссылки на исполняемые файлы, можно воспользоваться командой composer global config bin-dir --absolute:</p>
11
<p>Посмотреть содержание переменной окружения PATH в вашей системе можно с помощью команды echo:</p>
11
<p>Посмотреть содержание переменной окружения PATH в вашей системе можно с помощью команды echo:</p>
12
<h3>Пример</h3>
12
<h3>Пример</h3>
13
<p>Давайте создадим и опубликуем пакет, который для краткости и наглядности будет очень простым. Этот пакет будет состоять всего из двух исполняемых файлов, запуск которых выведет приветствие и прощание с Хекслетом.</p>
13
<p>Давайте создадим и опубликуем пакет, который для краткости и наглядности будет очень простым. Этот пакет будет состоять всего из двух исполняемых файлов, запуск которых выведет приветствие и прощание с Хекслетом.</p>
14
<p>Структура проекта:</p>
14
<p>Структура проекта:</p>
15
<p>Содержимое исполняемого файла sayHi:</p>
15
<p>Содержимое исполняемого файла sayHi:</p>
16
<p>Содержимое исполняемого файла sayBye:</p>
16
<p>Содержимое исполняемого файла sayBye:</p>
17
<p>Содержимое конфигурационного файла composer.json:</p>
17
<p>Содержимое конфигурационного файла composer.json:</p>
18
<p>Обсудим исполняемые файлы немного подробнее:</p>
18
<p>Обсудим исполняемые файлы немного подробнее:</p>
19
<ol><li>Чтобы запускать файлы из командной строки, пользователь должен иметь<strong>право на выполнение этого файла</strong>(атрибут x)</li>
19
<ol><li>Чтобы запускать файлы из командной строки, пользователь должен иметь<strong>право на выполнение этого файла</strong>(атрибут x)</li>
20
<li>Если исполняемый файл содержит код, то надо указать интерпретатор, который будет исполнять этот код при запуске исполняемого файла. Это делается с помощью<strong><a>шебанга</a></strong>. В примере выше мы указали<strong>php</strong>в качестве интерпретатора, а путь к нему задали с помощью специальной утилиты<strong><a>env</a></strong>. Мы решили не указывать абсолютный путь, потому что в разных системах<strong>php</strong>может находиться по совершенно разным путям</li>
20
<li>Если исполняемый файл содержит код, то надо указать интерпретатор, который будет исполнять этот код при запуске исполняемого файла. Это делается с помощью<strong><a>шебанга</a></strong>. В примере выше мы указали<strong>php</strong>в качестве интерпретатора, а путь к нему задали с помощью специальной утилиты<strong><a>env</a></strong>. Мы решили не указывать абсолютный путь, потому что в разных системах<strong>php</strong>может находиться по совершенно разным путям</li>
21
</ol><p>В итоге, мы подготовили пакет. После публикации он становится доступен для установки под именем hex/small-talk-with-hexlet.</p>
21
</ol><p>В итоге, мы подготовили пакет. После публикации он становится доступен для установки под именем hex/small-talk-with-hexlet.</p>
22
<p>Теперь установим этот пакет в систему глобально. Но сначала убедимся, что никаких символических ссылок в директории не существует:</p>
22
<p>Теперь установим этот пакет в систему глобально. Но сначала убедимся, что никаких символических ссылок в директории не существует:</p>
23
<p>Здесь с помощью фильтра grep мы попытались найти файлы, содержащие в своем имени строчку "say" (как наши ссылки в секции bin). Поиск не дал результатов, потому что до установки пакета таких файлов нет.</p>
23
<p>Здесь с помощью фильтра grep мы попытались найти файлы, содержащие в своем имени строчку "say" (как наши ссылки в секции bin). Поиск не дал результатов, потому что до установки пакета таких файлов нет.</p>
24
<p>Далее глобально устанавливаем пакет в систему:</p>
24
<p>Далее глобально устанавливаем пакет в систему:</p>
25
<p>Теперь воспользуемся grep и снова проверим директорию установки исполняемых файлов:</p>
25
<p>Теперь воспользуемся grep и снова проверим директорию установки исполняемых файлов:</p>
26
<p>Как и ожидалось, в этом каталоге находятся символические ссылки - об этом свидетельствует первый символ l, определяющий тип файла в строке атрибутов файла lrwxrwxrwx. Эти ссылки можно запускать из любой точки файловой системы:</p>
26
<p>Как и ожидалось, в этом каталоге находятся символические ссылки - об этом свидетельствует первый символ l, определяющий тип файла в строке атрибутов файла lrwxrwxrwx. Эти ссылки можно запускать из любой точки файловой системы:</p>
27
<p>Из примера видно, что мы можем успешно запускать одни и те же команды из разных директорий. Причины, по которым это происходит, мы подробно обсуждали выше.</p>
27
<p>Из примера видно, что мы можем успешно запускать одни и те же команды из разных директорий. Причины, по которым это происходит, мы подробно обсуждали выше.</p>
28
<h2>Что происходит при локальной установке</h2>
28
<h2>Что происходит при локальной установке</h2>
29
<p>В подавляющем большинстве случаев разработчики устанавливают пакеты не глобально, а локально. При такой установке пакеты привязываются к конкретному проекту и размещаются внутри его каталога по пути ./vendor/. При этом ссылки на исполняемые файлы устанавливаемых пакетов Composer размещает в каталоге ./vendor/bin.</p>
29
<p>В подавляющем большинстве случаев разработчики устанавливают пакеты не глобально, а локально. При такой установке пакеты привязываются к конкретному проекту и размещаются внутри его каталога по пути ./vendor/. При этом ссылки на исполняемые файлы устанавливаемых пакетов Composer размещает в каталоге ./vendor/bin.</p>
30
<p>Ссылки на исполняемые файлы локально установленных пакетов заточены под использование в скриптах, в секции scripts конфигурационного файла composer.json. Для этого существует особенный синтаксис. Эту тему мы проходили в<a>уроке, посвященном скриптам</a>.</p>
30
<p>Ссылки на исполняемые файлы локально установленных пакетов заточены под использование в скриптах, в секции scripts конфигурационного файла composer.json. Для этого существует особенный синтаксис. Эту тему мы проходили в<a>уроке, посвященном скриптам</a>.</p>
31
<p>Естественно, к символическим ссылкам можно также обратиться напрямую, указав нужный путь. Давайте рассмотрим это на примере, подключив к нашему разрабатываемому проекту small-talk-with-hexlet пакет<a>PHP_CodeSniffer</a>:</p>
31
<p>Естественно, к символическим ссылкам можно также обратиться напрямую, указав нужный путь. Давайте рассмотрим это на примере, подключив к нашему разрабатываемому проекту small-talk-with-hexlet пакет<a>PHP_CodeSniffer</a>:</p>
32
<p>Для примера возьмем команду composer require --dev some_package. Если установить пакет с флагом --dev в корневом каталоге проекта, он автоматически добавится в зависимости проекта, то есть в секцию require-dev файла composer.json. Этой возможностью мы и воспользовались.</p>
32
<p>Для примера возьмем команду composer require --dev some_package. Если установить пакет с флагом --dev в корневом каталоге проекта, он автоматически добавится в зависимости проекта, то есть в секцию require-dev файла composer.json. Этой возможностью мы и воспользовались.</p>
33
<p>Посмотрим, какие новые файлы появились в директории проекта:</p>
33
<p>Посмотрим, какие новые файлы появились в директории проекта:</p>
34
<p>Как и ожидалось, появился каталог ./vendor, в котором лежит код подключенного пакета и других пакетов, от которых он зависит.</p>
34
<p>Как и ожидалось, появился каталог ./vendor, в котором лежит код подключенного пакета и других пакетов, от которых он зависит.</p>
35
<p>Как узнать место, где Composer хранит ссылки на исполняемые файлы локально подключаемых пакетов? Это можно сделать с помощью команды composer config bin-dir.</p>
35
<p>Как узнать место, где Composer хранит ссылки на исполняемые файлы локально подключаемых пакетов? Это можно сделать с помощью команды composer config bin-dir.</p>
36
<p>Обратите внимание, что здесь нет команды global. В нашем случае это каталог ./vendor/bin. Заглянем в него:</p>
36
<p>Обратите внимание, что здесь нет команды global. В нашем случае это каталог ./vendor/bin. Заглянем в него:</p>
37
<p>В коде выше видно, что при установке PHP_CodeSniffer добавилось два исполняемых файла для запуска разных программ. Давайте запустим phpcs. Это<strong>линтер</strong>- утилита, которая проверяет код на соответствие стандартам:</p>
37
<p>В коде выше видно, что при установке PHP_CodeSniffer добавилось два исполняемых файла для запуска разных программ. Давайте запустим phpcs. Это<strong>линтер</strong>- утилита, которая проверяет код на соответствие стандартам:</p>
38
<p>Программа отработала корректно и завершилась молча - без дополнительного вывода отчета об ошибках. Так произошло, потому что в наших файлах не было никаких нарушений<a>оформления кода</a>.</p>
38
<p>Программа отработала корректно и завершилась молча - без дополнительного вывода отчета об ошибках. Так произошло, потому что в наших файлах не было никаких нарушений<a>оформления кода</a>.</p>
39
<p>Затем была попытка запустить исполняемый файл из командной строки только по имени, но она привела к неудаче - bash: phpcs: command not found. Командная оболочка просто не нашла файл - при глобальной установке все было бы по-другому.</p>
39
<p>Затем была попытка запустить исполняемый файл из командной строки только по имени, но она привела к неудаче - bash: phpcs: command not found. Командная оболочка просто не нашла файл - при глобальной установке все было бы по-другому.</p>
40
<h2>Выводы</h2>
40
<h2>Выводы</h2>
41
<p>В этом уроке мы рассмотрели общие принципы и отдельные нюансы работы Composer с исполняемыми файлами проекта. Важно отметить, что эти принципы характерны для большинства других пакетных менеджеров из разных языков - например,<a>менеджера пакетов Node.js</a>в JavaScript. Если в будущем вам придется столкнуться с чем-то подобным, вам будет намного проще.</p>
41
<p>В этом уроке мы рассмотрели общие принципы и отдельные нюансы работы Composer с исполняемыми файлами проекта. Важно отметить, что эти принципы характерны для большинства других пакетных менеджеров из разных языков - например,<a>менеджера пакетов Node.js</a>в JavaScript. Если в будущем вам придется столкнуться с чем-то подобным, вам будет намного проще.</p>
42
<p>Пример глобальной установки пакета:</p>
42
<p>Пример глобальной установки пакета:</p>
43
43