Как хранить дни недели, используя битовые поля?

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

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

Приложение написано на PHP. Я видел биты, используемые для хранения значений заголовка Вот. Есть тогда «вспомогательные» константы (HEADER_X_FORWARDED_ALL а также HEADER_X_FORWARDED_ALL которые действуют как «предварительные конфигурации» для все используемые заголовки или подмножество, используемое в AWS ELB-подобных средах (где некоторые заголовки не отправляются, поэтому «выключены»).

Итак, у меня есть пара вопросов, использующих этот тип данных для представления дней недель:

  1. Как бы я сохранил окончательное значение бита в MySQL? Как в столбце тип данных, длина и т. Д.

  2. Как бы я проверил, что день включен? Если у меня есть значение 0b0100000Как определить, используя побитовые операторы что вторник включен?

  3. Как «установить» дни, чтобы сохранить значение в базе данных? Так что, если у меня есть флажки в пользовательском интерфейсе, который представляет значения в виде массива, как бы я преобразовал что-то вроде:

Array
(
[days] => Array
(
[Monday] => 0
[Tuesday] => 1
[Wednesday] => 0
[Thursday] => 0
[Friday] => 0
[Saturday] => 0
[Sunday] => 0
)
)

… в немного значение, как 0b0100000снова используя побитовые операторы?

Если бы кто-то мог указать мне правильное направление для начала работы с битовыми значениями в PHP, я был бы очень благодарен!

1

Решение

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

/**
* Keys are ISO-8601 numeric representation
* of the days of the week
*/
$days = [
1 => 0b0000001, // Monday    =>  1
2 => 0b0000010, // Tuesday   =>  2
3 => 0b0000100, // Wednesday =>  4
4 => 0b0001000, // Thursday  =>  8
5 => 0b0010000, // Friday    => 16
6 => 0b0100000, // Saturday  => 32
7 => 0b1000000, // Sunday    => 64
];

Вы бы просто зациклились и проверили, установлен ли бит дня в значении (поразрядно и):

// The value you'd store in your database
$mondayToFriday = 31; // 1 + 2 + 4 + 8 + 16

foreach ($days as $n => $v) {

/**
* Get the day's name using strftime (has locale capability)
* strtotime("Sunday +n days") would work with ISO-8601 day
* numbers or PHP's date("w") (0 - 6 / Sunday - Saturday)
*/
$day = strftime("%A", strtotime("Sunday +{$n} days"));


echo "{$day}: " . (($v & $mondayToFriday) ? "Y" : "N") . PHP_EOL;

}

Что касается ваших флажков, вы можете просто построить двоичную строку из состояния каждого дня (0 или 1) и преобразовать ее в десятичную, используя bindec() (порядок, в котором они появляются в массиве, важен, вам нужно убедиться, что они правильно сопоставлены со значением соответствующего дня).

Учитывая ваш пример ввода и дни в этом примере, будет работать следующее:

$dec = bindec(strrev(implode("", $input["days"])));

Надеюсь, это подтолкнет вас в правильном направлении.

Вот пример для игры

0

Другие решения

Других решений пока нет …