Двухуровневое дерево MySQL + PHP

Немного хотелось бы описать процесс хранения двухуровневого дерева в MySQL, а так же его выгрузку одним запросом и формирование PHP массива для отображения в шаблоне и т.д.

Начну с структуры таблицы MySQL, на примере таблицы для хранения тегов Категория -> Тег.

Структура таблицы
CREATE TABLE table_tag (
  tag_id int(11) NOT NULL AUTO_INCREMENT COMMENT 'ИД тега',
  tag_name varchar(50) NOT NULL COMMENT 'ИМЯ тега',
  tag_type enum ('part', 'tag') NOT NULL DEFAULT 'tag' COMMENT 'ТИП тега',
  tag_parent int(10) UNSIGNED DEFAULT NULL COMMENT 'ИД родителя',
  PRIMARY KEY (tag_id),
  INDEX IDX_tag_parent (tag_parent),
  INDEX IDX_tag_type (tag_type)
)
ENGINE = MYISAM
COMMENT = 'Таблицы тегов';

Заполнение данными
Естественно, что заполнение данными для каждого конкретного случая будет если не уникально, то как минимум, отличаться. В данном случае, я буду использовать часть данных тегов уже существующего проекта.

Читать дальше

Преобразование строки HEX в число INT с учётом знака

PHP
Как оказалось, преобразование строки HEX в число INT с учётом знака, не является тривиальной задачей. И для такой конвертации не предусмотрено стандартной функции)
Но, если смотреть на сайте php.net не только описание стандартных функций, но и комментарии к ним, то можно обнаружить интереснейшие решения, одно из которых я и предлагаю Вашему вниманию.
/**
     * Конвертация HEX в INT с знаком
     *
     * @param $hex
     *
     * @return number
     */
    function hex2decSigned($hex)
    {
        // очистка от символов, не входящих в HEX
        $hex = preg_replace('/[^0-9A-Fa-f]/', '', $hex);

        // конвертация в десятичное значение:
        $dec = hexdec($hex);

        // максимальное десятичное значение, основанное на длине hex + 1:
        // количество бит в шестнадцатеричное число-это 8 бит для каждого 2 hex -> max = 2^n
        // использование 'pow(2,n) -' с '1 << n' - только для целых чисел и, следовательно, ограничен integer.
        $max = pow(2, 4 * (strlen($hex) + (strlen($hex) % 2)));

        // complement = maximum - конвертированный hex:
        $_dec = $max - $dec;

        // если dec значение больше, чем complement, имеем отрицательное значение (первый бит)
        return $dec > $_dec ? -$_dec : $dec;
    }

П.С. также эта функция может использоваться как частичная реализация C функции atoi(HEX) в PHP.

Преобразование многомерного массива PHP в простой XML

Преобразование многомерного массива PHP в простой XML (без атрибутов), только пары ключ=>значение

Очень коротко и быстро, хочу представить Вашему вниманию, небольшой класс PHP для преобразования многомерных массивов PHP в простой (без атрибутов) XML.

Большое спасибо автору Кевину Ватерсону за сие творение, которое мы успешно используем в своём API.


Читать дальше

Метод разбиения промежутка времени по дням с фиксацией времени начала и конца дня для указанного периода времени

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

Для примера представим, что клиент в абстрактной системе отчетов устанавливает период времени с 01:00 15.12.2014 по 23:00 21.12.2014 (1 неделя), за который он желает получить информацию. Фабрика отчетов на сервере умеет отдавать данные за период не более 24 часов. Вот тут и встает задача разбить промежуток времени на отрезки, с которыми потом можно работать в фабрике, т.е. на дни. Для получения можно воспользоватся функцией getDateTimeStartStopByDays (см. ниже), которая принимает в качестве параметров начало и конец периода в формате Timestamp. А на выходе мы получаем массив дат с указанием начала и конца каждого дня. Больше деталей смотрите в реализации метода.

Конечно можно работать только с датами в формате Unixtime, но в случае необходимости получения именно отформатированного массива дней, данный метод может Вам пригодится.

Коментарии по улучшению кода (стилистики, подхода, реализации и пр.) приветствуются!


Читать дальше

Экспорт данных из таблицы ExtJS Grid в таблицу Excel

Как сделать экспорт данных из таблицы ExtJS Grid в таблицу Excel?

Данное решение экспериментальное и имеет место для небольших, одностраничных, таблиц типа xtype:'grid' с хранилищем типа xtype:'store'.

Для реализации функционала, нам понадобится:
  • Библиотека ExtJS — JavaScript фреймворк. Если вы слышите это впервые, статья не будет полезна.
  • PHP сервер весрии 5+
  • PHPExcel — библиотека для создание Excel документа. Ссылка на сайт производителя.


Grid таблица
Для примера берём простейшую таблицу с тремя колонками ID, Имя, Дата. В данном примера поля имеют тип string (текст).


Так как статья получилась длинная, читайте продолжение под катом...

MySQL функция преобразование битовой маски в множество

MySQL функция преобразование битовой маски в множество, в данном случае, 10-тичного вида битовой маски.

Не так давно, я попытался написать подробную (с примерами, как для себя) инструкцию, применения битовой маски в MySQL запросах.
Сегодня мне пришлось немного расширить функционал своего модуля и дописать выборку из другой таблице по полю значений маски. Не буду увлекаться подробностями, скажу только, что кроме как разложить битовую маску на множество (строку) вида «1,3,7» для использование в условии:

WHERE `field` IN(1,3,7)

Для этих целей решил набросать маленькую MySQL функцию.
В качестве аргумента, функция принимает INT число — значение битовой маски (10 разряд).
Результатом работы функции будет строка вида «1,3,7», соответствующая номерам битов с значением 1.

Сама функция имеет комментарии и потому дополнительно описывать её не вижу смысла.

Читать дальше

Создание и использование битовой маски в PHP

PHP

Пример создание и использование битовой маски в PHP

Пишу этот материал только потому, что сам долго вникал, что к чему)))
Наверное, чтоб проще понять как использовать битовую маску (bitmask), нужно на примере показать, для чего она используется.

Пример использования битовой маски:
Задача
На сайте есть система опроса пользователей, которая содержит 10 вариантов ответа. Каждый вариант имеет свой уникальный номер — ID. Ответы нужно сохранять в БД.

Решение
Можно конечно, не заморачиваться и сделать для каждого варианта ответа отдельное поле в таблице результатов, но это не наши методы. Мы попробуем хранить все ответы в одном поле типа INT.

Предположим, что модуль голосования прислал нам массив результатов:
array(1,2,3,12);
это значит, что пользователь указал в голосовании пункты 1,2,3,12. Давайте представим результат нашего голосования как строку из 0 и 1, в которой 1 соответствуют выбранные в голосовании пункты. В результате такого преобразования мы получим число 100000000111 в двоичной системе, что будет соответствовать числу 2055 в десятичной системе.


Читать дальше

Преобразование поля LineString в массив точек JSON

Преобразование поля LineString в массив точек JSON, или как хранить координаты точки в MySQL

Недавно обнаружил в MySQL возможность хранить координаты ГЕО точек. Более подробно про функции для работы с геометрическими функциями в MySQL можно прочитать на страницах руководства:

Я не буду в этой статье описывать все функции для работы с типом LineString, так как там нет ничего сложного и достаточно информации в официальном руководстве. Хочу же более детально остановиться на конкретной задаче, а именно:

«Как из поля с типом LineString получить массив координат в формате JSON».
Для чего это нужно?
Например, есть таблица с маршрутами, каждая строка — это маршрут, в строке есть поле points типа LineString, в котором хранятся все координаты точек маршрута и нужно получить массив этих точек в читаемом формате.

Вариант решения предлагаю следующий:
  1. Создадим функции в MySQL для преобразования LineString в JSON в формате [{lat: val1, long: val2}, {lat: val3, long: val4}...].
  2. Создадим запрос для выгрузки из таблицы маршрутов.


Читать дальше