Phinx — миграции базы данных для вашего приложения

Phinx — миграции базы данных для вашего приложения

При разработке на любом из современных PHP фреймворков, мы используем систему миграций базы данных.

Миграция— создание/изменение структуры базы данных от одной версии до другой (не перенос данных, а именно работа со структурой), другими словами это что-то вроде системы контроля версий для вашей БД. Это очень удобный инструмент, позволяющий всем участникам команды разработки оставаться в курсе изменений в структуре БД используя Git.

Недавно для удобства разработки я решил добавить систему миграции для базы данных MySQL к проекту разрабатываемому без использования фреймворка с готовой системой миграции, теперь поделюсь с вами как это сделать с помощью пакета Phinx https://phinx.org/.

Установка Phinx

В момент написании этой заметки я работаю в Windows 10, Composer и PHP у меня установлены глобально. Приведенные ниже команды для вас могут немного отличаться.

Тут все просто, установим Phinx через Composer. Заходим в корневую папку проекта и выполняем команду:

composer require robmorgan/phinx

Композер загрузит сам пакет Phinx и все его зависимости.

Далее, чтобы убедиться, что все работает, можно выполнить команду:

php vendor/robmorgan/phinx/bin/phinx

Если все ОК, мы получим список возможных опций и команд пакета. На этом установка закончена.

Список возможных опций и команд пакета Phinx

Настройка Phinx

Проведем настройку Phinx для дальнейшей работы с ним, для этого выполним команду

php vendor/robmorgan/phinx/bin/phinx init

Эта команда создаст файл конфигурации phinx.php в корне проекта.

В первом блоке настроек paths указаны папки для хранения миграций и сидов (ниже объясняю что это) , оставим эти настройки без изменений. Просто создадим в корневой папки проекта 2 папки /db/migrations и /db/seeds

Далее в блоке environments заполним только настройки для окружения development (оно изначально указано как окружение по умолчанию):

'development' => [
            'adapter' => 'mysql',
            'host' => 'localhost',
            'name' => 'test',
            'user' => 'root',
            'pass' => '',
            'port' => '3306',
            'charset' => 'utf8',
        ],

Сохраняем файл phinx.php

Создание миграции с помощью Phinx

Для создании миграции (например создадим таблицу сообщений messages) необходимо выполнить команду

php vendor/robmorgan/phinx/bin/phinx create CreateTableMessages

После успешного выполнения команды в папке /db/migrations появится файл нашей миграции 20210310122116_create_table_messages.php

Этот файл содержит единственный метод change(), этот метод вызывается и при выполнении миграции и при откате.

Вместо метода change(), в классе миграции можно использовать два отдельных метода up() — вызывается при выполнении миграции и down() — вызывается при откате миграции.

Если в классе описан метод change(), то методы up() и down() будут игнорироваться.

Итак, мы создаем таблицу message, в ней будут поля id, content, date_time, для этого изменим метод change():

public function change(): void
    {
        // Создаем таблицу, поле id с автоинкрементом создастся автоматически
        $table = $this->table('messages');

        // Добавляем колонки в таблицу
        $table->addColumn('content', 'text')
              ->addColumn('date_time', 'datetime')
              ->create();
    }

Сохраняем и выполняем миграцию командой:

php vendor/robmorgan/phinx/bin/phinx migrate

Выполнение миграции Phinx

В нашей базе данных появилась таблица messages и таблица phinxlog — служебная таблица Phinx, куда он записывает информацию о миграциях.

Таблицы созданные с помщью Phinx

Откатить миграцию можно командой:

php vendor/robmorgan/phinx/bin/phinx rollback

Она отменит последнюю миграцию, т.е. отменит все действия описанные в методе change(). Выполним ее и увидим, что таблица messages исчезла, нам это не нужно, поэтому выполним команду migrate еще раз, чтобы создать таблицу назад.

Создание начальных данных

Если необходимо заполнить создаваемую таблицу какими либо начальными данными, нужно использовать механизм Phinx под названием Seeding.

Для создания Seed-а выполним команду:

php vendor/robmorgan/phinx/bin/phinx seed:create MessageSeeder

После выполнения в папке db/seeds/ появится файл MessagesSeeder.php который содержит метод run().

Изменим метод таким образом:

public function run()
    {
        // Данные, которые мы добавляем
        $data = [
            [
                'content'    => 'тестовое сообщение 1',
                'date_time' => date('Y-m-d H:i:s'),
            ],[
                'content'    => 'тестовое сообщение 2',
                'date_time' => date('Y-m-d H:i:s'),
            ]
        ];
        
        // Куда добавляем
        $messages = $this->table('messages');

        // Если мы хотим очистить таблицу перед выполнением сида, то добавляем ниже
        // $messages->truncate();

        $messages->insert($data)
              ->saveData();
    }

и выполним комаду:

php vendor/robmorgan/phinx/bin/phinx seed:run

Это команда выполнит все сиды, и наша таблица заполниться данными.

Чтобы выполнить конкретно сид MessageSeeder, а не все, нужно прописать команду таким образом:

php vendor/robmorgan/phinx/bin/phinx seed:run -s MessageSeeder

Выше в массив data мы добавили 2 сообщения, поскольку вручную большое количество добавлять не очень удобно 🙂 Чтобы добавить например 100 сообщений, можно воспользоваться какой-нибудь библиотекой для генерации фейковых данных, например популярной библиотекой Faker https://github.com/fzaninotto/Faker.

Для начала установим ее в наш проект через Композер:

composer require fzaninotto/faker

Далее изменим метод run() у нашего Seed-а:

public function run()
    {
        $faker = Faker\Factory::create();
        $data = [];
        for ($i = 0; $i < 100; $i++) {
            $data[] = [
                'conten'      => $faker->realText($maxNbChars = 150, $indexSize = 2),
                'date_time'       => date('Y-m-d H:i:s'),
            ];
        }
        
        // Куда добавляем
        $messages = $this->table('messages');

        // Если мы хотим очистить таблицу перед выполнением сида, то добавляем ниже
        // $messages->truncate();

        $messages->insert($data)
              ->saveData();
    }

Выполнив этот сид мы добавим в нашу базу данных сразу 100 тестовых записей.

Выше я описал необходимый минимум для начала работы с Phinx, о всех нюансах и возможностях можно узнать в официальной документации https://book.cakephp.org/phinx/0/en/index.html

Хостинг для ваших проектов