Лучшие практики для битовых флагов в PHP

ScopedTypeVariables действительно являются решением, но есть дополнительные требования к их использованию: вы должны указать явные forall s в типе подписей, объявляющих переменные, которые вы хотите использовать, например:

foo :: forall s. T s -> s -> s

Это так, что значение сигнатур в коде не зависит от того, включено ли расширение или нет.

14
задан Vilx- 9 January 2009 в 18:16
поделиться

7 ответов

В Вашем модель , объект имеет 8 булево свойств. Это подразумевает 8 булевских переменных (TINYINT для MySQL) столбцы в Вашей таблице базы данных и 8 методов считывания/методов установщика в Вашем объекте. Простой и стандартный.

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

CREATE TABLE mytable (myfield BIT(8));

хорошо, похож, мы собираемся иметь некоторые двоичные данные, происходящие здесь.

INSERT INTO mytable VALUES (b'00101000');

Ожидают, кто-то говорит мне снова, что обозначает каждая та 1 с и 0s.

SELECT * FROM mytable;
+------------+
| mybitfield |
+------------+
| (          | 
+------------+

, Что?

SELECT * FROM mytable WHERE myfield & b'00101000' = b'00100000';

WTF!? WTF!?

удары сам в поверхности

<час>

- между тем, в альтернативной вселенной, где феи играют с единорогами и программистами, не ненавидят DBAs... -

SELECT * FROM mytable WHERE field3 = 1 AND field5 = 0;

Счастье и солнечный свет!

36
ответ дан 1 December 2019 в 07:06
поделиться

Если действительно необходимо использовать битовые флаги, то используйте столбец SET для хранения их в DB, ассоциативного массива в коде и методах для превращения флагов вкл\выкл. Добавьте отдельные методы преобразовать массив в единственное целое число при необходимости в нем в том формате.

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

2
ответ дан 1 December 2019 в 07:06
поделиться

Я избегал бы битовых операций, поскольку становится очень трудно знать, какие флаги установлены путем рассмотрения только базы данных (если Вы не пытаетесь быть супер эффективными по некоторым причинам). Между другими двумя опциями я думаю, что это зависит, на том, сколько имеет значение каждого из этих флагов. Учитывая, что уже существует 8 из них, я склонился бы к другой таблице со многими многим отношения между ними (извините для выбора Вашего наименее любимого).

0
ответ дан 1 December 2019 в 07:06
поделиться

Принятие Вашего использования версии MySQL после 5.0.5 Вы могли определить столбец как BIT [ число битов здесь ]. Что касается стороны PHP я, вероятно, пошел бы с Get/SetFlagA, подходом Get/SetFlagB, нет никакой потребности в методе сброса, поскольку можно просто взять в булевской переменной к методу установки.

0
ответ дан 1 December 2019 в 07:06
поделиться

Один способ сохранить их в DB находится в единственном целочисленном поле как поразрядные флаги.

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

0
ответ дан 1 December 2019 в 07:06
поделиться

Хорошо, после размышления еще немного об этом я решил пойти с одной членской переменной на флаг. Я, возможно, использовал подход метода считывания/метода установщика, но я не использую их больше нигде в моем коде, таким образом, это было бы из стиля. Плюс, этот путь я также краткий обзор далеко от метода устройства хранения данных DB и может позже легко изменить это в случае необходимости.

Что касается DB - я собираюсь остаться с поразрядным целым числом на данный момент - главным образом, потому что я почти сделан с программным обеспечением и не хочу изменять это больше. Это не изменяет удобочитаемость вообще.

0
ответ дан 1 December 2019 в 07:06
поделиться

Я написал эту простую функцию, чтобы заполнить пробел между PHP и MySQL ENUMs:

function Enum($id)
{
    static $enum = array();

    if (func_num_args() > 1)
    {
        $result = 0;

        if (empty($enum[$id]) === true)
        {
            $enum[$id] = array();
        }

        foreach (array_unique(array_map('strtoupper', array_slice(func_get_args(), 1))) as $argument)
        {
            if (empty($enum[$id][$argument]) === true)
            {
                $enum[$id][$argument] = pow(2, count($enum[$id]));
            }

            $result += $enum[$id][$argument];
        }

        return $result;
    }

    return false;
}

Использование:

// sets the bit flags for the "user" namespace and returns the sum of all flags (15)
Enum('user', 'anonymous', 'registed', 'active', 'banned');

Enum('user', 'anonymous'); // 1
Enum('user', 'registed', 'active'); // 2 + 4 = 6
Enum('user', 'registed', 'active', 'banned'); // 2 + 4 + 8 = 14
Enum('user', 'registed', 'banned'); // 2 + 8 = 10

Вам просто нужно убедиться, что вы определяете перечисляемый список в том же порядке, что и MySQL ENUM.

1
ответ дан 1 December 2019 в 07:06
поделиться
Другие вопросы по тегам:

Похожие вопросы: