Доступ к базе данных Firebird из YII2

Так получилось, что мне понадобилось переносить интерфейс пользователя из связки Delphi + Firebird в WEB. Дабы не останавливать работу комплекса программ, решено было переносить формы постепенно, а для этого необходимо сохранить работу СУБД Firebird и подключаться к ней из web приложения. При разработке web-приложения я решил использовать фреймворк YII2. На этапе разработки мне не нужен полноценный HTTP сервер, вполне сойдет Denwer или XAMMP, или что-то еще. Я выбрал XAMMP т.к. в Денвере давно не обновляется версия PHP, а руками заниматься его обновлением не хочется, идем по пути наименьшего сопротивления. Изначально ни в XAMMP PHP, ни в YII2 нет возможности работать с СУБД Firebird, но при определенных танцах с бубном сделать это вполне реально. Итак, я буду полагать, что у Вас уже установлены: Windows 7 x64, XAMMP и YII2, Firebird 2.5.

Пути установки пакетов у меня (для себя вводите соответствующие корректировки):

  • Firebird 2.5 версия x64 (тип сервера значения не имеет) в C:\Program Files\Firebird\Firebird_2_5\
  • XAMMP установлен в D:\xampp\
  • YII2 установлен в D:\xampp\htdocs\yii\
  • БД расположена в пути D:\WORK\database\TBOT.GDB

Теперь можно начинать.

Установка поддержки Firebird для PHP


Для установки поддержки Firebird необходимо остановить сервер Apache в XAMMP. Для этого открываем консоль XAMMP и проверяем, что бы напротив сервиса Apache стояла кнопка «Start» т.е. сервис не запущен, иначе нажимаем «Stop».



Открываем любым редактором файл конфигурации PHP D:\xampp\php\php.ini и находим в нем строчку:

;extension=php_pdo_firebird.dll

Убираем ";" в начале т.е. раскомментируем и сохраняем. Драйвер PDO, используемый YII2 для доступа к СУБД, включен. Однако так просто ничего не заработает, теперь надо скопировать стандартную библиотеку доступа к СУБД fbclient.dll. Тут необходимо быть внимательным т.к. у нас установлен Windows x64 и сервер Firebird x64, а XAMMP это 32-х разрядное приложение. Соответственно библиотека fbclient.dll должна быть скомпилирована для той версии клиента (в данном случае XAMMP, точнее PHP в составе XAMMP), который используется для доступа к БД. 32-х разрядная версия библиотеки находится в каталоге WOW64 каталога установки Firebird т.е. берем файл C:\Program Files\Firebird\Firebird_2_5\WOW64\fbclient.dll и копируем в следующие пути:

  • в рабочий каталог PHP D:\xampp\php\
  • в SYSTEM32 C:\Windows\System32\. По идее копировать сюда не обязательно, но я использую билиотеку в других проектах и что бы не плодить копии по всей системе, копируем сюда.

В некоторых источниках советуют скопировать в D:\xampp\apache\bin\, но в моем случае это ни на что не повлияло. Да и, по идее, не могло повлиять т.к. сервер Apache запускает PHP и ему самому никакие дополнительные библиотеки доступа не нужны.

Рекомендую так же проверить наличие библиотеки PDO для доступа к Firebird, файл D:\xampp\php\ext\php_pdo_firebird.dll.

Запускаем сервер Apache (см. рис. выше), нажимаем «Start» в консоли XAMMP. На данный момент неплохо убедиться, что драйвер PDO для Firebird появился в системе, я потратил целый день, пока понял, что драйвер не подключен. Система обработки ошибок YII2 в этом деле оказалась слабым помощником т.к. сообщала о другой ошибке в другом месте. Не загружался список таблиц в Model Generator gii, а перед этим была ошибка установки расширения для доступа к Firebird, поэтому связать ошибку с неподключенным драйвером PDO было не очевидно.

Создаем файл test-fb.php в рабочем каталоге фреймворка YII2 D:\xampp\htdocs\yii\, в нем ишем код:

<?php
	foreach (PDO::getAvailableDrivers() as $drv) {
		echo $drv."<br/>";
	}
?>

Данный код выводит список подключенных в PHP драйверов PDO. Запускаем браузер и набираем в адресной строке URL localhost/yii/test-fb.php, в ответ получаем страничку со списком подключенных драйверов.

firebird
mysql
sqlite

Обязательно убеждаемся, что в списке есть драйвер firebird. Драйверы MySQL и SQLite всегда подключены по умолчанию.

Установка расширений YII2 для доступа к Firebird


Для для подключения к Firebird в YII2 существуют два расширения.

  • yii2-firebirddb от Sergey Rusakov. Судя по описанию представляет собой адаптацию расширения от YII1. Недостатком является то, что это сборка dev, а не stable, поэтому в дальнейшем придется менять «minimum-stability» в composer.json, что приведет к загрузке нестабильных версий других расширений YII2 при обновлении через Composer.
  • yii2-firebird от Edgard Lorraine Messias. Судя по исходникам данного расширения и тем же багам, это yii2-firebirddb от Sergey Rusakov, переведенная из ветки dev в ветку stable.

Я опишу последовательно установку обоих расширений. Начну со второго расширения yii2-firebird т.к. оно имеет статус stable.

Установка yii2-firebird

Открываем файл D:\xampp\htdocs\yii\composer.json и находим в нем кусок кода:

...
    "require": {
        "php": ">=5.4.0",
        "yiisoft/yii2": ">=2.0.5",
        "yiisoft/yii2-bootstrap": "*",
        "yiisoft/yii2-swiftmailer": "*"
...

Добавляем в конец через запятую строчку «edgardmessias/yii2-firebird»: "*", получим:

...
    "require": {
        "php": ">=5.4.0",
        "yiisoft/yii2": ">=2.0.5",
        "yiisoft/yii2-bootstrap": "*",
        "yiisoft/yii2-swiftmailer": "*",
	"edgardmessias/yii2-firebird": "*"
...

Обратите внимание, после добавленной строки запятой быть не должно т.к. она добавлена в конце массива и наличие запятой при выполнении Composer даст ошибку. Хотя сам PHP и допускает наличие запятой в конце списка элементов массива перед закрывающей скобкой, Composer это не допускает.

Итак, мы указали Composer, что необходимо загрузить расширение yii2-firebird. Запускаем командную строку, делаем текущим каталог D:\xampp\htdocs\yii\ и даем последовательно две команды:

composer update
composer install

Внимательно изучаем вывод Composer на предмет ошибок, проверяем наличие каталога D:\xampp\htdocs\yii\vendor\edgardmessias\yii2-firebird\. Расширение установлено.

Настроим доступ к БД. В документации к yii2-firebird сказано, что необходимо изменить конфигурацию. Если внимательно изучить файл конфигурации D:\xampp\htdocs\yii\config\web.php, находим строку (примерно 40-я строка):


'db' => require(__DIR__ . '/db.php'),

из чего становится ясно, что редактировать настройки подключения к БД необходимо в файле D:\xampp\htdocs\yii\config\db.php. Открываем его и приводим к виду:


<?php
return [
    'class' => 'edgardmessias\db\firebird\Connection',
    'dsn' => 'firebird:dbname=localhost:D:/WORK/database/TBOT.GDB;charset=WIN1251',
    'username' => 'SYSDBA',
    'password' => 'masterkey'
];

Хочу обратить внимание на некоторые моменты:

  • в первой строке конфигурации указан класс Connection с пространством имен
  • в строке 'dsn' указан драйвер доступа firebird, так же кодировка БД должна быть указана в строке 'dsn'
  • путь к БД указан через прямой слэш, тогда как в Windows пути принято указывать через обратные слеши. На самом деле нет разницы как указывать т.к. в D:\xampp\htdocs\yii\vendor\edgardmessias\yii2-firebird\src\PdoAdapter.php в конструкторе класса (строка 37) есть код:

    ...
        public function __construct($dsn, $username, $password, $driver_options = [])
        {
            // Windows OS paths with backslashes should be changed
            $dsn = str_replace("\\", "/", $dsn);
    ...
    

    т.е. в строке dsn всегда делается замена обратных слешей на прямые.
  • При использовании обратных слешей помните об экранировании символов в PHP, поэтому обратные слеши должны повторяться по 2 раза. т.е. строка dsn должна выглядеть так:

    
        'dsn' => 'firebird:dbname=localhost:D:\\WORK\\database\\TBOT.GDB;charset=WIN1251',
    

  • при подключении к локальной БД указывать localhost в dsn не обязательно, я просто показал как делать подключение к внешнему серверу по протоколу TCP/IP

Установка yii2-firebirddb

Как я указал выше, yii2-firebirddb имеет статус dev, в связи с этим есть небольшие особенности установки этого расширения.

Теперь в файл D:\xampp\htdocs\yii\composer.json в секцию «require» добавляем путь загрузки расширения yii2-firebirddb "srusakov/firebirddb": "*". А поскольку библиотека статуса dev, то над секцией «require» находим и меняем "minimum-stability": "stable", на "minimum-stability": "dev",. Получаем такой вид (обратите внимание на первую и последнюю строки):

...
    "minimum-stability": "dev",
    "require": {
        "php": ">=5.4.0",
        "yiisoft/yii2": ">=2.0.5",
        "yiisoft/yii2-bootstrap": "*",
        "yiisoft/yii2-swiftmailer": "*",
	"edgardmessias/yii2-firebird": "*"
...

Мы указали Composer, что необходимо загрузить расширение yii2-firebirddb. Запускаем командную строку, делаем текущим каталог D:\xampp\htdocs\yii\ и даем последовательно две команды:

composer update
composer install

Проверяем на отсутствие ошибок и наличие каталога D:\xampp\htdocs\yii\vendor\srusakov\firebirddb\. Расширение установлено.

Замечание

В документации к yii2-firebirddb сказано, что еще надо прописать путь к репозиторию для загрузки расширения. В моем случае это, кроме ошибки, ничего не дало, но на всякий случай опишу как это сделать.

Сначала установите GIT для Windows. Скачать можно по ссылке https://git-scm.com/download/win. Перезапустите консоль командной строки что бы переменная окружения PATH обновилась. Проверьте в командной строке, что бы проходила команда

git

в ответ должна вывестись подсказка по использованию утилиты в командной строке.

В файле D:\xampp\htdocs\yii\composer.json после закрывающей скобки раздела «require» пишем путь к репозиторию, получается:

...
"require": {
        "php": ">=5.4.0",
        "yiisoft/yii2": ">=2.0.5",
        "yiisoft/yii2-bootstrap": "*",
        "yiisoft/yii2-swiftmailer": "*",
	"edgardmessias/yii2-firebird": "*",
	"srusakov/firebirddb": "*"
    },
"repositories":[{
        "type":"git",
        "url":"http://github.com/srusakov/yii2-firebirddb"
  }],
...

Обратите внимание на последние 4 строки. Дальше стандартно запускаем командную строку, делаем текущим каталог D:\xampp\htdocs\yii\ и даем последовательно две команды:

composer update
composer install

Проверяем на отсутствие ошибок и наличие каталога D:\xampp\htdocs\yii\vendor\srusakov\firebirddb\. Расширение установлено.

Открываем файл конфигурации подключения к БД D:\xampp\htdocs\yii\config\db.php, вносим изменения, получаем:


<?php

return [
            'class' => 'yii\db\Connection',
            'dsn' => 'firebird:dbname=localhost:D:/WORK/database/TBOT.GDB;charset=WIN1251',
            'username' => 'sysdba',
            'password' => 'masterkey',
            'charset' => 'utf8', //вот тут надо еще разбираться с кодировками, но это тема для другого материала
            'pdoClass' => 'srusakov\firebirddb\PDO',
            'schemaMap' => [
                                'firebird' => 'srusakov\firebirddb\Schema' // FireBird
                            ]
];

Проверка работоспособности

Самый простой способ проверить правильность установки расширений, драйверов и параметров подключения к БД — подключиться. Запускаем утилиту gii из YII2 и открываем Model Generator. Ссылка для открытия gii http://localhost/yii/web/?r=gii, выбираем кнопку «Start» в разделе Model Generator, или по прямой ссылке http://localhost/yii/web/index.php?r=gii/default/view&id=model
Если Model Generator откроется без ошибок, значит всё установлено и работает верно т.к. Model Generator загружает в себя список таблиц БД т.е. подключается к Firebird. Если получаете ошибку загрузки страницы, скорее всего у Вас в БД нет ни одной таблицы и список таблиц возвращается пустой. Создайте хоть одну таблицу и попробуйте еще раз. Так же проверьте правильность путей к БД в конфигурации (файл D:\xampp\htdocs\yii\config\db.php).

Заключение


  1. Хочу отметить разность подхода к работе расширений. Расширение yii2-firebirddb работает с классом Connection из стандартного для YII2 пространства имен, но при этом использует свой драйвер PDO для доступа к Firebird. Расширение yii2-firebird расширяет стандартный Connection своим.
  2. Оба расширения не работают с BLOB полями. Описание этого бага тут https://bugs.php.net/bug.php?id=61183. Поскольку для меня это не очень актуально, я этим вопросом не занимался, предлагаю создавать в БД просмотры (views), в которых преобразовывать поле blob в varchar. Тем более varchar допускает размер текста до 32Кб. Для медиа (картинки, виде и т.д.) этого мало, но я работаю в основном с текстовыми данными и этого вполне достаточно. Второй вариант — прочитать описание бага, так предлагают наложить патч, который это должен исправить. Если кто-то это сделает, отпишитесь в комментах, внесу изменения в статью.
  3. Для тех программистов, кто давно использует PHP и YII2 данный материал может показаться излишне подробным. Например часто достаточно сказать «измените конфигурацию» и всё. Однако для тех, кто начинает миграцию с Delphi на PHP и YII2 такая фраза мало что скажет т.к. надо еще найти файлы, в которых лежит конфигурация. Тоже самое касается и команд для обновления расширений.
Поделиться публикацией
Похожие публикации
AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Подробнее
Реклама
Комментарии 16
  • 0
    Открыл статью, ожидая увидеть изучение протокола общения с БД и его портирование под yii2 в виде пакета, но увы. Статья ну совсем для «самых маленьких», может стоило это указать?
    Создаем файл test-fb.php в рабочем каталоге фреймворка YII2 D:\xampp\htdocs\yii\, в нем ишем код:

    Зачем? Чем вас канонический php -m не устроил (в интерпритации под окна):
    php -m | find "pdo"
    
    • 0
      Согласен, совсем уж для «самых маленьких», часть касаемая настройки среды и подключения драйвера можно было смело опустить.
      То что в делфи использовался win1251 не обязывает использовать его в web, используйте utf8, сэкономите время в будущем.

      зы
      с чем связан переезд именно на пхп?
      Работа с fb через php не очень хорошая идея, в случае нагрузки, конечно. В fb создание соединения, особенно для classic, не дешево и под нагрузкой это будет съедать время + доп нагрузка на сервер БД. Предпочтительнее эту работу доверить сервису с возможностью поддерживать постоянное соединение с БД. Сервис можно написать на том же делфи, пусть он отдает данные по рест, либо напрямую в браузер либо через php.
      • 0
        Возможно потом, на определенном этапе, просто переедут на MySQL или PostgreSQL.
        • 0
          Вы абсолютно правы!
          Я не зря написал в начале статьи, что предполагается постепенный переход. Более того, переход будет сделан на MySQL. Причина простая — самые дешевые хостинги дают, как правило, только MySQL.
          Спрашивается, почему бы сразу не перезалить всю БД на MySQL и не извращаться.
          К сожалению это непросто т.к. в Firebird я активно использую хранимые процедуры (как и лбой другой дельфист). Я зык хранимых процедур у MySQL и FB разный, хоть и похожий. Переписать каждую процедуру тоже требуется время, а это означает, что пока буду переписывать, необходимо останавливать всю работу. А еще и отлаживать их надо. Одному перелопатить сотню процедур, это не так быстро. Да и переписывать их на MySQL нет никакого смысла, тут лучше делать обработку в контроллерах YII2.
          А так, как описано в статье — можно на первое время уже выдать результат работы некоторых форм (терминах дельфи) хотя бы в режиме просмотра в web.
        • 0
          конечно не обязывает, но моя БД была под дельфи еще со времен «царя гороха» и кодировка win1251. Конечно, в проектах на web я использую только utf8, это гораздо удобнее.
        • 0
          тоже вариант, не спорю
          • 0
            А про «самых маленьких» и указано, см. п. 3 в «Замечании»
            • +1
              а Вы пробовали сравнить результат своего и моего варианта?
              в первом случае выводит
              D:\xampp\php>php -m | find "pdo"
              pdo_mysql
              pdo_sqlite

              в браузере:
              URL: http://localhost/yii/test-fb.php
              firebird
              mysql
              odbc
              sqlite

              Кстати, вот вопрос, почему так? php.exe запускается один и тот же, из каталога D:\xampp\php\php.exe, только во втором случае это делает Apache.
              • –1
                А вы пробовали чуть-чуть подумать над смыслом команды? Уберите find «pdo» и выведет все модули…
                • 0
                  А если CLI-версия и расширение Apache используют разные php.ini? Над этим подумали?
                  • 0
                    Я бы задумался над психической уравновешенностью человека, использующего разные версии php для cli/apache/php-fpm при работе с yii2.
                    • 0
                      Конкретно с Yii, возможно, и так, но в иных ситуациях это может быть полезно — к примеру, если под CLI у вас свои консольные скрипты для административных задач, а под Apache/php-fpm/uWSGI/etc — продакшен для сайтов клиентов, которым нельзя позволять всё то, что позволено вашим скриптам. Более того, если у вас php-fpm или uWSGI, вам может быть крайне полезным заводить пулы/вассалы с разными наборами опций (как минимум), а как максимум — разными php.ini. Так что вариант, предложенный автором, всё же более универсален.
                      • 0
                        спасибо за поддержку, был бы рейтинг, поставил бы +
                        Я, конечно, и не думал про CLI, разграничение прав, но идея была в том, что работающий скрипт работает в своем окружении и его работоспособность надо проверять именно в том окружении, в котором потом будет работать весь фреймворк. Будет другой сервер/экземпляр сервера, может будет всё другое.
                  • 0
                    ну не надо совсем меня считать идиотом. Не иметь большого опыта работы с YII и быть идиотом — разные вещи.
                    я пробовал и
                    D:\xampp\php>php -m
                    и
                    D:\xampp\php>php -m > 1.txt
                    и поиск по тексту
                    и
                    D:\xampp\php>php -m | find "firebird"
                    и
                    D:\xampp\php>php -m | find "f"
                    Пробовал в лоб указать через ключ -c конкретный конфигурационный файл
                    D:\xampp\php>php -c php.ini -m | find "f"
                    ну нету модуля.

                    Остался один вариант, но возиться с ним не охота. Скорее всего Apache создает свой набор переменных окружения и именно он влияет на подгрузку драйвера. По идее можно сваять скриптик, глянуть переменные и повторить их тупо через runme.bat
              • +2
                «Обратите внимание, после добавленной строки запятой быть не должно т.к. она добавлена в конце массива и наличие запятой при выполнении Composer даст ошибку. Хотя сам PHP и допускает наличие запятой в конце списка элементов массива перед закрывающей скобкой, Composer это не допускает.»

                Наверное потому что файл композера это не массив на пхп, а json? :-D

                Не думаете?
                • –1
                  просто не стал об этом подробно писать. Думаю и так понятно, что это разные вещи. Может Вас в заблуждение ввело слово «Хотя...». На самом деле понятно, что это разные интерпретаторы.

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