Подавляющее большинство библиотек и проектов существуют не сами по себе. Типовые задачи имеют какие-то общие решения и вынесены в отдельные пакеты (какими-то разработчиками). Благодаря этим пакетам, разработчики экономят время, не делая то, что уже сделано до них. Подобных общих решений сотни тысяч. Вот лишь некоторые примеры:
Любые из этих пакетов можно установить к себе в проект используя Composer. Это одно из его главных предназначений.
Предположим, что наш пакет зависит от библиотеки tightenco/collect. Эту библиотеку мы будем активно использовать в наших курсах позже. Разберём процесс установки:
Для начала нужно понять, под каким именем существует наша библиотека в Packagist. Тут вариантов два: либо мы уже знаем, как в случае tightenco/collect, либо мы нашли библиотеку на GitHub и хотим выяснить её имя. Часто имя можно извлечь из строки установки, которая есть в файле README.md:
Если её нет, вы всегда можете узнать имя, открыв файл composer.json (прямо на GitHub) и прочитав значение свойства name.
{
"name": "tightenco/collect",
"description": "Collect - Illuminate Collections as a separate package.",
"keywords": ["laravel", "collection"]
}
Когда имя найдено, можно приступать к установке пакета. Для этого нужно перейти в директорию с нашим проектом и запустить там следующую команду:
# Это локальная установка в конкретный проект
composer require tightenco/collect
Эта команда не только устанавливает зависимость в текущий проект, но и автоматически добавляет его в секцию require файла composer.json. Такая установка является локальной (в команде нет слова global), то есть пакет ставится именно в текущий проект. Секция require теперь выглядит примерно так:
"require": {
"tightenco/collect": "^5.7"
}
Кроме того, Composer создаст файл composer.lock в корне проекта. Этот файл должен храниться в репозитории, а его значение я объясню в следующем уроке.
Со временем, чем больше пакетов добавляется в текущий проект, тем больше размер секции require. В больших проектах это могут быть сотни зависимостей. Ниже пример взятый из php-package:
"require": {
"tightenco/collect": "^5.6",
"nesbot/carbon": "^1.26",
"danielstjules/stringy": "^3.1"
}
Возникает вопрос, а куда помещается код этих пакетов? Код пакетов, установленных локально, сохраняется в директории vendor, которую Composer автоматически создаёт во время установки пакетов. Эта директория находится в корне проекта:
tree -L 1
.
├── Makefile
├── README.md
├── bin
├── composer.json
├── composer.lock
├── phpunit.xml
├── psysh.php
├── src
├── tests
└── vendor # Вот она
Эта директория считается служебной и программист никогда не работает с ней напрямую. Более того, она должна быть добавлена в .gitignore, так как нет смысла хранить её в репозитории. Composer создаёт её самостоятельно.
Кроме обычных зависимостей, которые нужны для работы пакета, существуют специальные зависимости, необходимые только во время разработки. Такое разделение понадобилось в целях оптимизации. Практически любой пакет во время разработки использует тестовый фреймворк, который не нужен для работы самого пакета, но нужен для тестирования. Поэтому нет смысла тащить его с собой в рабочее окружение. Это негативно влияет как на размер пакета, так и на скорость его загрузки. Такие зависимости устанавливаются с помощью дополнительной опции --dev:
composer require --dev phpunit/phpunit
В файле composer.json они появляются внутри секции require-dev
"require-dev": {
"phpunit/phpunit": "*"
}
Теперь самое интересное — как, собственно, использовать установленные зависимости? В первую очередь нужно смотреть документацию конкретной библиотеки на GitHub. Обычно там есть примеры либо ссылка на описание. Например в последующих уроках мы будем пользоваться библиотекой funct. Эта библиотека содержит десятки полезных функций для работы с разными типами данных. Ниже пример вызова:
<?php
use Funct;
use Funct\Strings;
Funct\firstValue(null, null, 'foo_bar'); // => 'foo_bar'
Funct\notEmpty('fooBar'); // => true
Strings\camelize('data_rate'); //'dataRate'
После того как в проект устанавливаются зависимости, изменённые файлы заливаются на GitHub. К ним относится как composer.json, в который добавились описания зависимостей, так и файлы с исходным кодом где эти зависимости используются. А вот директория vendor остаётся на локальной машине.
Представьте что с вами работает другой разработчик, который клонирует репозиторий к себе и пытается запустить проект локально. Что произойдёт? Запуск кода завершится с ошибкой. В проекте используются внешние библиотеки, но их физически нет. Директория vendor не создана.
Чтобы исправить это, сразу после клонирования нужно выполнить установку зависимостей. Для этого в Composer есть ещё одна команда – install:
composer install
# ниже примерный вывод
Loading composer repositories with package information
Installing dependencies (including require-dev) from lock file
Warning: The lock file is not up to date with the latest changes in composer.json. You may be getting outdated dependencies. Run update to update them.
Package operations: 1 install, 19 updates, 18 removals
- Removing symfony/yaml (dev-master)
- Removing symfony/stopwatch (dev-master)
- Removing symfony/polyfill-php73 (dev-master)
- Removing symfony/filesystem (dev-master)
- Removing symfony/event-dispatcher (dev-master)
- Removing symfony/console (dev-master)
- Removing symfony/config (dev-master)
- Removing satooshi/php-coveralls (v1.1.0)
- Removing psy/psysh (dev-master)
- Removing padraic/phar-updater (dev-master)
- Removing padraic/humbug_get_contents (1.1.2)
symfony/translation-contracts suggests installing symfony/translation-implementation
Generating autoload files
Установка пакетов — это идемпотентная операция, её можно запускать сколько угодно раз без риска что-либо поломать.
Зарегистрируйтесь на сайте https://packagist.org/ (аккаунт пригодится для участия в проектах)
Установите зависимость:
# Выполнять в корне проекта
composer require tightenco/collect
Создайте в корне вашего проекта директорию src, а внутри неё файл Runner.php. Добавьте следующий код (мы его запустим в одном из следующих уроков):
<?php
namespace Hexlet\Php\Runner;
function run()
{
$collection = collect(['taylor', 'abigail', null])->map(function ($name) {
return strtoupper($name);
});
return $collection;
}
Вам ответят команда поддержки Хекслета или другие студенты.
Выделите текст, нажмите ctrl + enter и отправьте его нам. В течение нескольких дней мы исправим ошибку или улучшим формулировку.
Загляните в раздел «Обсуждение»:
Статья «Ловушки обучения»
Вебинар «Как самостоятельно учиться»
Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.
Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно.
Наши выпускники работают в компаниях:
С нуля до разработчика. Возвращаем деньги, если не удалось найти работу.
Зарегистрируйтесь или войдите в свой аккаунт