Я пытаюсь сохранить выбранные будни в одном поле в БД. Похоже, что побитовое идеально подходит для этого, но PHP не дает ожидаемого результата, и я не знаю почему.
mon tue wnd thu fri sat sun
1 1 1 1 1 1 1
1 2 4 8 16 32 64
Итак, чтобы выбрать вт и пт: 18
(0100100)
и, например, чтобы проверить, выбрано ли воскресенье: decbin(18) & decbin(64)
(должен вернуть «пусто»),
но результаты являются неожиданными.
Это потому, что вам нужно дополнить эти двоичные строки левой линией с ведущими нулями до одинаковой длины. decbin () создает строку, которая отбрасывает все ведущие нули. Вы and
такие строки как:
10010 // 18
1000000 // 64
Либо использовать str_pad () также добавьте начальные нули к фиксированной длине или сохраните вызов функции и используйте sprintf для выполнения базового преобразования и заполнения за один шаг
sprintf('%08b', 18) & sprintf('%08b', 64)
Вам совсем не нужно работать с двоичными строками, чтобы работать с битовыми флагами.
Объявите свои дни как целые числа 1,2,4,8 и т. Д.
Чтобы сделать значение, которое является понедельником и пятницей, просто двоичные ИЛИ значения.
Чтобы проверить, что число содержит день, двоичные И их и убедитесь, что результат равен дню вашей проверки.
Хотя технически это все двоичные операции, на самом деле вам не нужно когда-либо видеть или использовать двоичные строки.
Некоторые примеры с результатами дампа ниже … пожалуйста, игнорируйте мое использование экстракта, это было просто быстрее
<?php
// Day names
$dayNames = array(
'monday',
'tuesday',
'wednesday',
'thursday',
'friday',
'saturday',
'sunday',
);
// Bit values
$dayValues = array();
foreach($dayNames as $key => $value) {
$dayValues[$value] = 1 << $key;
}
var_dump($dayValues);
extract($dayValues);// Monday and Tuesday
$monANDtue = $monday | $tuesday;
var_dump($monANDtue);
var_dump(decbin($monANDtue));// Monday and Sunday
$monANDsun = $monday | $sunday;
var_dump($monANDsun);
var_dump(decbin($monANDsun));// Is on Monday?
$isOnMonday = ($monANDsun & $monday) == $monday;
var_dump($isOnMonday);
// Is on Tuesday?
$isOnTuesday = ($monANDsun & $tuesday) == $tuesday;
var_dump($isOnTuesday);
// Is on Tuesday?
$isOnSunday = ($monANDsun & $sunday) == $sunday;
var_dump($isOnSunday);
?>
и выход
/vhost/virtual/sandbox/public/index.php:27
array(7) {
[monday] = int(1) 1
[tuesday] = int(1) 2
[wednesday] = int(1) 4
[thursday] = int(1) 8
[friday] = int(2) 16
[saturday] = int(2) 32
[sunday] = int(2) 64
}
/vhost/virtual/sandbox/public/index.php:33
int(1) 3
/vhost/virtual/sandbox/public/index.php:34
string(2) "11"
/vhost/virtual/sandbox/public/index.php:40
int(2) 65
/vhost/virtual/sandbox/public/index.php:41
string(7) "1000001"
/vhost/virtual/sandbox/public/index.php:47
bool(true)
/vhost/virtual/sandbox/public/index.php:51
bool(false)
/vhost/virtual/sandbox/public/index.php:55
bool(true)