PHP, SQLite и регистронезависимость | Erinome Lane
Несмотря на объявленную поддержку UTF, встраиваемая СУБД SQLite3 по умолчанию не умеет делать регистронезависимую сортировку, сравнение и операции по преобразованию строк над буквами, не входящими в английский алфавит. Для решения этой проблемы разработчики SQLite рекомендуют использовать расширение ICU, с подключением которого станет возможным выбирать различные кодировки и иметь возможность пользоваться регистронезависимыми операциями сравнения любых символов кроме латиницы. Вот только описаний, как это сделать для php-mod-sqlite3, найти толком нельзя, да и объем ICU превышает размер самой библиотеки SQLite! Для embedded-применений – например, в OpenWrt – такое не годится.
Давным-давно, в далекой-далекой галактике… оказалось, что много лет назад некий товарищ по имени ioannis в рамках решения означенной проблемы создал небольшое расширение SQLite, по сути представляющее собой урезанную версию ICU, из которой был выброшен код, который в 95% случаев никогда не потребуется. Таким образом удалось сократить размер расширения с мегабайт до символических 70-90 кбайт (в зависимости от архитектуры и компилятора). Копия исходного сообщения осталась доступна на mail-archive.com, и хотя оригинальная ссылка на исходный код расширения sqlite3_unicode.c неработоспособна, его все еще можно найти в интернете, а также мы добавили его в наш архив.
Возможности расширения#define SQLITE3_UNICODE_FOLD – поддержка нелатинских символов функцией FOLD() – +10КБ
#define SQLITE3_UNICODE_LOWER – поддержка нелатинских символов функцией LOWER() – +10КБ
#define SQLITE3_UNICODE_UPPER – поддержка нелатинских символов функцией UPPER() – +10КБ
#define SQLITE3_UNICODE_TITLE – поддержка нелатинских символов функцией TITLE() – +10КБ
#define SQLITE3_UNICODE_UNACC – преобразование accented-символов в обычные, для русского языка не очень актуально – +30КБ
#define SQLITE3_UNICODE_COLLATE – заменяет COLLATION типа NOCASE на новый, в котором при сравнении не учитывается регистр в т. ч. и для нелатинских символов.
#define SQLITE3_UNICODE_UNACC_AUTOMATIC – попытаться применять UNACC в функции LIKE и операциях сравнения с COLLATE NOCASE.
Что характерно, функциональность, которая не требуется, может быть отключена путем убирания соответствующих #define для экономии места и увеличения производительности (вряд ли, впрочем, существенного).
Теперь разберемся, как собрать это расширение и задействовать его в cli-версии SQLite и в модуле для PHP.
Сборка под LinuxДля начала, скачиваем и распаковываем исходный код SQLite – нам потребуются заголовочные файлы из него. Можно использовать любую версию: я брал amalgamation без autoconf – она меньше. В тот же каталог копируем sqlite3_unicode.c.
Далее, корректности ради, открываем sqlite3_unicode.c текстовым редактором и вписываем вверху директиву:
/* we want shared library. only. */ #define SQLITE_ENABLE_UNICODE 1
Этим мы указываем, что собираемся компилировать shared-библиотеку. С другой стороны – соответствующий #if в коде расширения написан таким своеобразным образом, что этого можно и не делать.
Затем следует непосредственно процесс компиляции. Предполагается, что пакеты из набора build-essentials уже установлены в системе – во всяком случае, здесь потребуется gcc:
gcc -shared -o sqlite3_unicode.so sqlite3_unicode.c
Закрывая глаза на ряд warning’ов, получаем готовую библиотеку.
При работе с cli-версией потребуется разместить полученный sqlite3_unicode.so в каталоге с остальными системными библиотеками, либо же выполнить export следующего вида:
export LD_LIBRARY_PATH="/path/to/library/dir:$LD_LIBRARY_PATH"
Затем открываем cli и пишем команду .load sqlite3_unicode. Если ошибок не возникло – значит, расширение успешно загрузилось.
Для загрузки расширения в PHP потребуется в php.ini выставить корректный путь к месту расположения библиотеки в перараметре sqlite3.extension_dir. Затем в скрипте используем команду вида $db->loadExtension(‘sqlite3_unicode.
Вот и всё – теперь сравнения с COLLATE NOCASE будут регистронезависимыми не только для латиницы, но и для русских букв.
Сборка под OpenWrtТеперь попробуем побороть Buildroot от OpenWrt и кросс-компилировать это расширение в toolchain’е для запуска на роутере. В конечном счете, именно ради этого весь процесс и затевался – на ПК-то нет проблемы установить ICU, в отличие от встраиваемых систем. Надо признать, что борьба с Buildroot’ом для меня оказалась намного сложнее, чем все поиски решения проблемы с регистрозависимостью в целом и попытки разобраться, как его собирать в обычных условиях, в частности.
В конечном счете, после бессчетных неудачных попыток, я остановился на варианте формирования отдельного пакета, содержащего только это расширение с выставленным параметром DEPENDS на libsqlite3 и включенным в его состав С-файле с исходным кодом. Скачать готовый пакет можно в нашем архиве.
Его можно распаковать в каталог “package” корневой директории Buildroot’а, а затем нужно в make menuconfig выбрать пакет libsqlite3_unicode и запустить его сборку при помощи команды make package/libsqlite3_unicode/compile.
После установки полученного ipk на роутер подключение данного расширения производится аналогичным ранее описанному способом. Обратите внимание, что имя расширения для OpenWrt – libsqlite3_unicode.so, его размещение по умолчанию – /usr/lib.
This entry was posted in Сеть и интернет and tagged linux, openwrt, грабли. Bookmark the permalink.
Средство управления базой данных SQLite
Обзор и поиск
Просмотр содержимого ваших таблиц или поиск определенных строк
Обновление, вставка, удаление
Редактирование содержимого ваших таблиц, вставка новых строк или удаление существующих
Изменить таблицы
Добавить, удалить или переименовать столбцы или изменить их тип – в т.ч. возможности SQLite не поддерживаются!
Импорт и экспорт
Импорт и экспорт файлов CSV или дампов SQL
Следуя духу SQLite
phpLiteAdmin — это веб-инструмент администрирования базы данных SQLite, написанный на PHP с поддержкой SQLite3 и SQLite2. Следуя духу плоской файловой системы, используемой SQLite, phpLiteAdmin состоит из одного исходного файла, phpliteadmin.php, который помещается в каталог на сервере, а затем открывается в браузере. Установка не требуется. Доступные операции, набор функций, интерфейс и взаимодействие с пользователем сопоставимы с phpMyAdmin.
Easy
Для установки и использования
Мощный
Может делать больше, чем сам SQLite
Облегченный
Только один файл ~ 250 КБ
Настраиваемый
10+ языков и 10+ тем
НАШИ СЧАСТЛИВЫЕ КЛИЕНТЫ
Демо
Попробуйте phpLiteAdmin сейчас
Скачать
Получить последнюю стабильную версию
Система отслеживания проблем
Сообщить об ошибке или запросить функции
Группа обсуждения
Присоединиться к беседе
Конфиденциальность и файлы cookie: этот сайт использует файлы cookie. Продолжая использовать этот веб-сайт, вы соглашаетесь на их использование.
Выпущен phpLiteAdmin 1.9.8
Наконец-то, спустя долгое время, сегодня была выпущена новая стабильная версия phpLiteAdmin. Скачать phpLiteAdmin 1.9.8 теперь Он содержит множество улучшений по сравнению с 1.9.7.1. Одной из основных новых функций является автоматическое завершение и подсветка синтаксиса в полях редактора SQL. Внимание: этот выпуск также включает исправления безопасности. phpliteAdmin от 1.9.5 до 1.9.7.1 (и некоторые 1.9.8-dev[…]
Предупреждение системы безопасности: версия для разработчиков phpLiteAdmin 1.9.8-dev
В разрабатываемых версиях 1.9.8-dev обнаружена проблема безопасности были опубликованы между 22 января 2017 г. и 17 августа 2017 г. (сегодня). Эти версии позволяют злоумышленникам изменять или удалять существующие базы данных или создавать новые базы данных без аутентификации. Стабильные версии не затрагиваются. Если вы клонировали phpLiteAdmin из git, вы вероятно, тоже повлияло. В таком случае[…]
Выпущен phpLiteAdmin 1.9.7
Сегодня был выпущен phpLiteAdmin 1.9.7. Он исправляет пару ошибок, добавляет несколько новых функций, а также устраняет некоторые проблемы, связанные с безопасностью. Поэтому всем пользователям phpLiteAdmin рекомендуется обновиться до последней версии. Список изменений можно найти в вики. Для новой версии требуется как минимум PHP 5.2.4 (ранее: PHP 5.2.0). Благодаря[…]
phpliteadmin.org теперь обслуживает SSL с шифрованием — благодаря letsencrypt!
Наш веб-сайт phpliteadmin.org теперь обслуживается зашифрованным SSL благодаря letsencrypt! Если вы еще не слышали об этом, letsencrypt предлагает бесплатные сертификаты с проверкой домена. Мы гордимся тем, что являемся одними из первых веб-сайтов, которые используют letsencrypt для обслуживания нашего веб-сайта с шифрованием SSL. Если вы также хотите зашифровать свой веб-сайт или установку phpliteadmin с помощью[…]
У phpLiteAdmin появился новый веб-сайт
Долгое время у phpLiteAdmin была только страница проекта Google. Мы разместили демоверсию, страницу пожертвований и другие вещи на других хостах, так как google не предложил подходящего варианта. Теперь, когда код Google закрылся и мы перенесли наш проект в bibucket, я подумал, что пришло время создать настоящий веб-сайт для[…]
ПредыдущийСледующий
pecl — Обновление библиотеки SQLite для php 5.4
Задавать вопрос
Спросил
Изменено 7 лет, 3 месяца назад
Просмотрено 406 раз
Моя версия php 5.4
Вот что я получаю в phpinfo
pdo_sqlite Драйвер PDO для SQLite 3.x включен Библиотека SQLite 3.6.20
Мне очень нужно обновить этот драйвер.
В PHP 5.3 вы могли бы сделать это с помощью таких команд, как yum install php5-sqlite , но теперь, похоже, мне придется использовать pecl.
Для команды pecl install pdo_sqlite я получаю следующее:
/var/tmp/PDO_SQLITE/sqlite_driver.c: В функции do_callback: /var/tmp/PDO_SQLITE/sqlite_driver.c:311: ошибка: 'zend_fcall_info' не имеет члена с именем 'object_pp' /var/tmp/PDO_SQLITE/sqlite_driver.c: На верхнем уровне: /var/tmp/PDO_SQLITE/sqlite_driver.c:636: предупреждение: инициализация из несовместимого типа указателя /var/tmp/PDO_SQLITE/sqlite_driver.c: в функции make_filename_safe: /var/tmp/PDO_SQLITE/sqlite_driver.c:645: ошибка: «struct _php_core_globals» не имеет члена с именем «safe_mode» /var/tmp/PDO_SQLITE/sqlite_driver.c:645: ошибка: 'CHECKUID_CHECK_FILE_AND_DIR' необъявлено (первое использование в этой функции) /var/tmp/PDO_SQLITE/sqlite_driver.c:645: ошибка: (Каждый необъявленный идентификатор сообщается только один раз /var/tmp/PDO_SQLITE/sqlite_driver.c:645: ошибка: для каждой функции, в которой она появляется.) /var/tmp/PDO_SQLITE/sqlite_driver.c: в функции pdo_sqlite_handle_factory: /var/tmp/PDO_SQLITE/sqlite_driver.