我正在重新分解应用程序,其中一个数据库表以列的形式存储一周中的几天。每一天都可以“开启”或“关闭”。
on和off的概念让我觉得这些数据可以更简洁地表示为位。但我以前没有使用原始位作为数据类型。
该应用程序是用PHP编写的。我见过用于存储标头值here的位。然后有“辅助”常量(HEADER_X_FORWARDED_ALL
和HEADER_X_FORWARDED_ALL
充当正在使用的所有标头的“预配置”,或者用于AWS ELB的子集类似的环境(没有发送一些标题,所以“关闭”)。
所以我有几个问题使用这种数据类型来表示几周的几天:
我如何在MySQL中存储最终的比特值?如列数据类型,长度等。
我如何检查一天是否“开启”?如果我的值为0b0100000
,如何确定使用周二“开启”的bitwise operators?
如何“设置”天数来保存数据库中的值?因此,如果UI中的复选框将值作为数组提交,我将如何转换为:
Array
(
[days] => Array
(
[Monday] => 0
[Tuesday] => 1
[Wednesday] => 0
[Thursday] => 0
[Friday] => 0
[Saturday] => 0
[Sunday] => 0
)
)
...再次使用按位运算符,类似0b0100000
的值?
如果有人能指出我在PHP中开始使用位值的正确方向,我将非常感激!
答案 0 :(得分:0)
您可以存储所选日期的小数值。所以作为一个非常基本的例子:
/**
* 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"])));
希望这会让你朝着正确的方向前进。