Если видео недоступно для просмотра, попробуйте выключить блокировщик рекламы.

Ключевая программа в экосистеме PHP — Composer. Она выполняет очень много функций, которые не представляется возможным рассмотреть в рамках текущего курса. Общая рекомендация состоит в том, чтобы периодически посматривать на её команды и изучать информацию по ним. Ключевая задача, которую решает Composer — управление зависимостями, и именно о ней мы поговорим. Процесс установки самого Composer для каждой операционной системы описан в официальном руководстве:

Для успешной установки и настройки Composer, необходимо хотя бы немного разбираться с работой командных интерпретаторов. Рекомендуем пройти соответствующий курс на Хекслете, если вы этого ещё не сделали

Кроме самого Composer установите следующие программы, используя пакетный менеджер вашей операционной системы:

Убедитесь, что Composer работает:

$ composer
   ______
  / ____/___  ____ ___  ____  ____  ________  _____
 / /   / __ \/ __ `__ \/ __ \/ __ \/ ___/ _ \/ ___/
/ /___/ /_/ / / / / / / /_/ / /_/ (__  )  __/ /
\____/\____/_/ /_/ /_/ .___/\____/____/\___/_/
                    /_/
Composer version 1.8.0 2018-12-03 10:31:16

# Тут много вывода

Запуск Composer без аргументов, выведет весь список доступных команд с их описанием. Пробегитесь по ним, чтобы сформировать первое впечатление.

Практически с самого зарождения программирования (когда код стал храниться в памяти компьютера), появилась идея повторного использования кода не только в рамках одного проекта, но и в других проектах. Например, функции для работы с датами, математическими формулами, всевозможными расчётами одни и те же во всех проектах, где они требуются. Подобное переиспользование приводит к резкому возрастанию производительности. Программисты современности могут сосредоточиться на решении уникальных задач бизнеса, вместо создания своих велосипедов для решения инфраструктурных задач. Особенно просто стало жить во времена Git и GitHub.

Первоначально общий код выносился в файлы, которые программисты часто держали на своих собственных компьютерах и копировали из проекта в проект. Такой способ обладает рядом существенных недостатков:

  1. Сложно передать другим
  2. У каждого своя собственная копия решений одних и тех же решений (немного разных решений)
  3. Доработкой занимается только автор
  4. В сумме много разных копий без возможности быстрого обновления
  5. Из-за того, что код копируется прямо в другой проект, он, как правило, модифицируется и становится специфичным

Если использовать Git, то часть проблем решается автоматически. Мы можем сказать, что набор общих файлов называется "библиотека", а конечные проекты начинают использовать библиотеки как написанные нами, так и сторонними разработчиками. Но тут возникает следующая сложность — когда таких библиотек становится много, то у них также появляется общий код более низкого уровня. Например, финансовые библиотеки могут использовать функции для преобразования валют. Чтобы подобный код не дублировался, хочется его вынести в общее место. Этот процесс может продолжаться бесконечно. Одни библиотеки зависят от других, те в свою очередь от третьих и так далее. С точки зрения переиспользования кода всё хорошо, большое число маленьких библиотек, решающих всевозможные задачи, позволяет быстро двигаться вперёд, но с точки зрения управления появляются проблемы:

  1. Необходимо ввести понятие "версия", а библиотеки начинают зависеть не только друг от друга, но и от версий друг друга. Почему это нужно? Очень просто. Предположим, что создатель библиотеки обновил её, изменив сигнатуры функций (другое число параметров, другие параметры, другой возврат), или, как говорят, сломал обратную совместимость. В такой ситуации наша первоначальная библиотека перестанет работать (если мы обновим вторую библиотеку), так как она рассчитывала на одно поведение зависимой библиотеки, а получила другое.
  2. Необходимо стандартизировать способ создания библиотек, только в таком случае станет возможным автоматизировать процесс их соединения без ручного управления. Скажу навскидку, типичный веб-проект может зависеть от сотни библиотек, которые в свою очередь зависят от других библиотек. Общее число зависимостей может легко перевалить за тысячу. Вручную управлять таким зоопарком не представляется возможным.
  3. Проблема, описанная выше, также требует наличия автоматизированного средства по управлению зависимостями. Обновлению, установке и удалению.

Всеми этими вопросами занимаются пакетные менеджеры. В большинстве языков пакетный менеджер поставляется прямо с самим языком, так как в современном мире сложно представить себе код, который не использует ни одной зависимости.

Терминология

В PHP используются следующие понятия.

Пакет — собственно, та самая библиотека, которую мы либо пишем, либо используем в проекте как зависимость.

Репозиторий (Registry) — хранилище пакетов PHP, которое называется Packagist. Каждый желающий может опубликовать пакет в Packagist, потратив буквально минуту времени, а остальные смогут его использовать. В хранилище, на текущий момент, сотни тысяч пакетов и их количество растёт. Исходный код пакетов, как правило, хранится на гитхабе, но это не обязательно. Пакеты в PHP никак не связаны с Git и GitHub.

Глобальная установка пакетов

Многие пакеты в PHP представляют из себя законченные программы. Их можно установить и запустить как обычную утилиту командной строки. Попробуем установить утилиту phploc, которая умеет считать количество строк и сущностей в PHP-проекте. Инструкция по установке подобных пакетов обычно присутствует на странице репозитория на GitHub.

$ composer global require phploc/phploc

Отмечу несколько моментов:

  • global означает, что установка глобальная, то есть пакет ставится в операционную систему как обычная программа
  • Чтобы shell увидел программу, установленную глобально, нужно правильно настроить переменную окружения $PATH

Процесс установки занимает некоторое время, в течение которого видно как скачивается не только сам пакет, но и его зависимости. Дальше ничего делать не нужно, так как phploc создан утилитой командной строки, он сразу готов к использованию.

$ phploc src

phploc 4.0.0 by Sebastian Bergmann.

Directories                                          3
Files                                               10

Size
  Lines of Code (LOC)                             1882
  Comment Lines of Code (CLOC)                     255 (13.55%)
  Non-Comment Lines of Code (NCLOC)               1627 (86.45%)
  Logical Lines of Code (LLOC)                     377 (20.03%)
    Classes                                        351 (93.10%)
      Average Class Length                          35
        Minimum Class Length                         0
        Maximum Class Length                       172
      Average Method Length                          2
        Minimum Method Length                        1
        Maximum Method Length                      117
    Functions                                        0 (0.00%)
      Average Function Length                        0
    Not in classes or functions                     26 (6.90%)

Если что-то пошло не так, убедитесь что вы всё правильно настроили:

  • Изучите вывод echo $PATH. Есть ли там путь до исполняемых файлов Composer.
  • Проверьте, все ли установилось командой which phploc.

Проект

Composer работает таким образом, что объединяет понятия "проект" (приложение или application) и "пакет" в одно целое. В общем случае считается, что проект, в отличие от пакета, это конечный продукт, который никуда не публикуется, что довольно очевидно. Если компания делает сайт на PHP, то этот сайт, хотя и использует публичные зависимости, сам по себе хранится в приватном репозитории и никуда не утекает. Но с точки зрения Composer все происходит одинаково. Причём под проектом понимается не обязательно что-то большое. Даже если ваш проект (файл) состоит из 3 строчек кода и использует зависимости, вам понадобится работать с ним как с полноценным проектом. Начинается всё просто. Необходимо выполнить команду composer init в той папке, где вы собираетесь писать код.

$ 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 <[email protected]>
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": "[email protected]"
        }
    ],
    "require": {}
}        
Do you  confirm generation [yes]?

После этого вам предложат ответить на десяток вопросов. Если вы не понимаете значение некоторых вопросов, то смело жмите Enter, потом все можно будет поправить.

Когда вопросы закончатся, Composer покажет конечный результат в виде JSON. JSON — это текстовый формат для представления структурированных данных. Если вы не знакомы с ним, то не стоит переживать, формат это не язык программирования. Достаточно выучить несколько правил по формированию данных в виде JSON для того, чтобы чувствовать себя комфортно.

{
    "name": "hex/example",
    "description": "example package",
    "authors": [
        {
            "name": "hex",
            "email": "[email protected]"
        }
    ],
    "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",
---------^

Обычно любые сообщения с "неожиданными" (unexpected) символами или строками говорят о наличии синтаксической ошибки.

Воспользуйтесь валидаторами JSON для проверки корректности своего файла. Например, jsonlint.com или другими подобными инструментами, которые можно загуглить по запросу "json validator".

Самостоятельная работа

  • Создайте директорию my-project в любом удобном месте вашего компьютера
  • Создайте проект в директории my-project, используя composer init

В результате в папке проекта должен оказаться файл composer.json

Мы учим программированию с нуля до стажировки и работы. Попробуйте наш бесплатный курс «Введение в программирование» или полные программы обучения по Node, PHP, Python и Java.

Хекслет

Подробнее о том, почему наше обучение работает →