Ключевая программа в экосистеме PHP — это Composer. Она выполняет так много функций, что мы не сможем рассмотреть всё в рамках этого курса. Мы советуем периодически просматривать ее команды и изучать информацию по ним. Основная задача, которую решает Composer — управление зависимостями. Именно о нем мы поговорим в этом уроке.
Чтобы установить Composer, изучите официальное руководство для Windows и Linux. На MacOS все немного проще — Composer устанавливается через Homebrew командой brew install composer
.
Для успешной установки и настройки Composer нужно немного разбираться в работе с командными интерпретаторами. Рекомендуем пройти соответствующий курс на Хекслете, если вы этого еще не сделали.
Кроме самого Composer, установите следующие программы, используя пакетный менеджер вашей операционной системы:
- git
- curl
Убедитесь, что Composer работает:
composer
______
/ ____/___ ____ ___ ____ ____ ________ _____
/ / / __ \/ __ `__ \/ __ \/ __ \/ ___/ _ \/ ___/
/ /___/ /_/ / / / / / / /_/ / /_/ (__ ) __/ /
\____/\____/_/ /_/ /_/ .___/\____/____/\___/_/
/_/
Composer version 1.8.0 2018-12-03 10:31:16
# Здесь много вывода
Запуск Composer без аргументов выведет весь список доступных команд с их описанием. Пробегитесь по ним, чтобы сформировать первое впечатление.
Почти с зарождения программирования появилась идея повторно использовать код не только в рамках одного проекта, но и в других проектах. Например, во всех проектах используются одни и те же функции для работы с датами, математическими формулами и расчетами. Такое переиспользование привело к росту производительности — современные программисты могут сосредоточиться на решении уникальных задач бизнеса, не тратя время на изобретение велосипеда под инфраструктурные задачи. Работать стало еще проще, когда появились Git и GitHub.
Первоначально общий код выносился в файлы, которые программисты держали на своих компьютерах и копировали из проекта в проект. У такого способа есть ряд существенных недостатков:
- Код сложно передать другим
- У разных программистов хранятся разные копии одних и тех же решений
- Доработкой кода занимается только его автор
- В сумме много разных копий без возможности быстрого обновления
- Код копируется прямо в другой проект, поэтому он модифицируется и становится специфичным
Git автоматически решает часть этих проблем. С его помощью можно создавать наборы общих файлов — библиотеки. Потом в конечных проектах можно использовать такие библиотеки причем как написанные нами, так и сторонними разработчиками.
Но тут возникает новая сложность — когда библиотек становится много, у них появляется общий код более низкого уровня. Например, финансовые библиотеки могут использовать функции для преобразования валют. Чтобы подобный код не дублировался, хочется его вынести в общее место. Этот процесс может продолжаться бесконечно. Одни библиотеки зависят от других, которые зависят от третьих и так далее.
С точки зрения переиспользования кода все хорошо — большое число маленьких библиотек решают всевозможные задачи, что позволяет быстро двигаться вперед. Но с точки зрения управления, появляются проблемы:
- Нужно вводить понятие «версия», потому что библиотеки начинают зависеть не только друг от друга, но и от версий друг друга. Для примера представим, что в новой версии библиотеки ее автор изменил параметры функций — это ломает обратную совместимость. В такой ситуации можно обновить вторую библиотеку, но тогда первая перестанет работать. Она рассчитывала на одно поведение зависимой библиотеки, а получила — другое.
- Нужно стандартизировать способ создания библиотек, чтобы автоматизировать их соединение. Типичный веб-проект может зависеть от сотни библиотек, которые в свою очередь зависят от других библиотек. Общее число зависимостей может легко перевалить за тысячу — вручную управлять таким зоопарком невозможно.
- Из-за проблемы выше нужно автоматизированное средство управления зависимостями — для их обновления, установки и удаления.
Всеми этими вопросами занимаются пакетные менеджеры. Обычно пакетный менеджер поставляется вместе с языком программирования, потому что сложно представить себе современный код без единой зависимости.
Терминология
В PHP есть два важных понятия:
- Пакет — это та самая библиотека, которую мы пишем или используем в проекте как зависимость
- Репозиторий — это хранилище пакетов PHP, которое называется Packagist. Любой пользователь может за пару минут опубликовать пакет в Packagist, а все остальные смогут его использовать. Сейчас в хранилище больше трехсот тысяч пакетов, и их количество растет. Обычно исходный код пакетов хранится на GitHub, но это не обязательно.
Глобальная установка пакетов
Многие пакеты в PHP — это законченные программы. Их можно установить и запустить как обычную утилиту командной строки. Эти пакеты ставятся в системные директории и не связаны с конкретным проектом.
Попробуем установить утилиту phpcs
, которая анализирует код на соответствие стандартам. Инструкция по установке подобных пакетов обычно есть на странице репозитория на GitHub:
# Composer скачает исходный код этого пакета и положит его куда-то к себе
# Конкретный путь зависит от настроек и операционной системы
composer global require 'squizlabs/php_codesniffer=*'
- Здесь global означает, что установка глобальная, то есть пакет ставится в операционную систему как обычная программа
- Чтобы командный интерпретатор увидел программу, установленную глобально, нужно правильно настроить переменную окружения
$PATH
, добавив в нее путь к исполняемым файлам Composer. Его можно узнать, выполнив в терминале командуcomposer global config bin-dir
Установка занимает некоторое время, в течение которого видно, как скачивается сам пакет и его зависимости. Дальше ничего делать не нужно — phpcs
создан утилитой командной строки, он сразу готов к использованию:
# Как аргумент эта утилита принимает путь до файла или директории с исходным кодом
# Здесь в качестве опции мы указываем также и стандарт PSR12
phpcs --standard=PSR12 path/to/file
FILE: /home/hexlet/projects/test/test.php
-------------------------------------------------------------------------------
FOUND 1 ERROR AFFECTING 1 LINE
-------------------------------------------------------------------------------
12 | ERROR | [x] Each imported trait must have its own "use" import statement
-------------------------------------------------------------------------------
PHPCBF CAN FIX THE 1 MARKED SNIFF VIOLATIONS AUTOMATICALLY
-------------------------------------------------------------------------------
Time: 21ms; Memory: 6MB
Если что-то пошло не так, убедитесь, что вы все правильно настроили:
Изучите вывод
echo $PATH
и поищите, есть ли там путь до исполняемых файлов Composer:echo $PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/home/hex/.composer/vendor/bin
С помощью команды
which phpcs
проверьте, все ли установилось:which phpcs /home/hex/.composer/vendor/bin/phpcs
Ошибки
Во время установки пакетов Composer может ругаться на различные ошибки. Например, так:
- Installation request for phar-io/manifest 1.0.x-dev -> satisfiable by phar-io/manifest[1.0.x-dev].
- phar-io/manifest 1.0.x-dev requires ext-dom * -> the requested PHP extension dom is missing from your system.
Problem 2
- Installation request for phar-io/manifest dev-master -> satisfiable by phar-io/manifest[dev-master].
- phar-io/manifest dev-master requires ext-dom * -> the requested PHP extension dom is missing from your system.
Problem 3
- Installation request for phpunit/php-code-coverage 7.0.x-dev -> satisfiable by phpunit/php-code-coverage[7.0.x-dev].
- phpunit/php-code-coverage 7.0.x-dev requires ext-dom * -> the requested PHP extension dom is missing from your system.
Problem 4
Эти ошибки говорят нам, что устанавливаемые библиотеки хотят использовать PHP-расширение, которое не установлено в систему. Это прямо написано в выводе:
requires ext-dom * -> the requested PHP extension dom is missing from your system
Когда вы встречаете такую ошибку, то первым делом нужно посмотреть на название расширения. Здесь это dom. Затем нужно поискать инструкцию, которая объяснит, как установить это расширение в вашу операционную систему. Проще всего это сделать таким запросом: php <название операционной системы> <название расширения> install extension.
Проект
Composer – это универсальный способ описывать любой код на PHP, который подходит для работы и с библиотекой, и с полноценным сайтом. В любом случае внутри будет Composer. Фактически любой новый проект начинается не с написания кода, а с инициализации Composer. Для этого нужно запустить команду init
. Она задаст несколько вопросов и на основе ваших ответов сформирует файл composer.json.
Если вы не понимаете значение некоторых вопросов, смело жмите Enter — потом все можно будет поправить:
composer init
Welcome to the Composer config generator
This command will guide you through creating your composer.json config.
Package name (<vendor>/<name>) [hex/hex]: hex/example
Description []: example package
Author [, n to skip]: hex <hex@hexlet.io>
Minimum Stability []:
Package Type (e.g. library, project, metapackage, composer-plugin) []:
License []:
Define your dependencies.
Would you like to define your dependencies (require) interactively [yes]? n
Would you like to define your dev dependencies (require-dev) interactively [yes]? n
{
"name": "hex/example",
"description": "example package",
"authors": [
{
"name": "hex",
"email": "hex@hexlet.io"
}
],
"require": {}
}
Do you confirm generation [yes]?
Когда вопросы закончатся, Composer покажет конечный результат в виде JSON — это текстовый формат для представления структурированных данных. Если вы не знакомы с ним, это не критично. Достаточно выучить несколько правил формирования данных в виде JSON, чтобы чувствовать себя комфортно:
{
"name": "hex/example",
"description": "example package",
"authors": [
{
"name": "hex",
"email": "hex@hexlet.io"
}
],
"require": {}
}
Если вас все устраивает, то Composer создаст файл composer.json. Именно этот файл является ключевым. В нем описывается абсолютно все, что касается зависимостей. С этого момента все команды composer, непосредственно связанные с проектом, выполняются именно в той директории, в которой находится файл composer.json.
Имя пакета в composer.json, состоит из двух частей:
- vendor name — имя, под которым вы зарегистрированы в Packagist
- project name
Причем vendor name уникален глобально, то есть все пользователи имеют свое собственное неповторимое имя, а вот project name должен быть уникален только в пределах vendor name.
Composer рекомендует именовать пакет словами в нижнем регистре и в качестве разделителя использовать дефис: например, dependency-injection.
Проблемы
Иногда в файле composer.json содержатся синтаксические ошибки — нарушения правила форматирования JSON. В таком случае при попытке сделать что-то с проектом будут появляться подобные ошибки:
[Seld\JsonLint\ParsingException]
"./composer.json" does not contain valid JSON
Parse error on line 2:
"name": "mokevnin/myproject",
---------^
Обычно любые сообщения с неожиданными символами или строками говорят о синтаксической ошибке.
Воспользуйтесь валидаторами JSON для проверки корректности своего файла. Например, для этого подходит jsonlint.com и другие подобные инструменты, которые можно найти по запросу json validator.
Самостоятельная работа
- В проекте hexlet-php инициализируйте PHP-проект
- Заполните пустые поля файла composer.json. Чтобы было проще, изучить описание каждого поля в документации Composer
- Добавьте все изменения на GitHub
Дополнительные материалы
Остались вопросы? Задайте их в разделе «Обсуждение»
Вам ответят команда поддержки Хекслета или другие студенты
Для полного доступа к курсу нужен базовый план
Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.