如何使用位域存储星期几?
How to store days of week using bit field?
我是 re-factoring 一个应用程序,其中一个数据库表将星期几存储在列中。每一天都可以是“开”或“关”。
打开和关闭的概念让我觉得可以将此数据更简洁地表示为位。但是我以前没有使用原始位作为数据类型。
申请是在PHP写的。我见过用于存储 header 值 here 的位。然后有“辅助”常量(HEADER_X_FORWARDED_ALL
和 HEADER_X_FORWARDED_ALL
作为“pre-configurations” 用于 all header 被使用,或 sub-set 用于 AWS ELB-like 环境(其中一些 header 未发送,因此“关闭”)。
所以我有几个问题使用这种数据类型来表示星期几:
如何将最终位值存储在 MySQL 中?如列数据类型、长度等
我如何检查某一天是否“开启”?如果我有值 0b0100000
,我如何使用 bitwise operators 确定星期二是“开”?
如何“设置”天数以将值保存在数据库中?因此,如果我在 UI 中有复选框将值作为数组提交,我将如何转换如下内容:
Array
(
[days] => Array
(
[Monday] => 0
[Tuesday] => 1
[Wednesday] => 0
[Thursday] => 0
[Friday] => 0
[Saturday] => 0
[Sunday] => 0
)
)
…像0b0100000
这样的位值,再次使用按位运算符?
如果有人能为我指明开始使用 PHP 中的位值的正确方向,我将不胜感激!
您可以存储所选日期的十进制值。所以作为一个非常基本的例子:
/**
* 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"])));
希望这会把你推向正确的方向。
Here's an example to play with
我是 re-factoring 一个应用程序,其中一个数据库表将星期几存储在列中。每一天都可以是“开”或“关”。
打开和关闭的概念让我觉得可以将此数据更简洁地表示为位。但是我以前没有使用原始位作为数据类型。
申请是在PHP写的。我见过用于存储 header 值 here 的位。然后有“辅助”常量(HEADER_X_FORWARDED_ALL
和 HEADER_X_FORWARDED_ALL
作为“pre-configurations” 用于 all header 被使用,或 sub-set 用于 AWS ELB-like 环境(其中一些 header 未发送,因此“关闭”)。
所以我有几个问题使用这种数据类型来表示星期几:
如何将最终位值存储在 MySQL 中?如列数据类型、长度等
我如何检查某一天是否“开启”?如果我有值
0b0100000
,我如何使用 bitwise operators 确定星期二是“开”?如何“设置”天数以将值保存在数据库中?因此,如果我在 UI 中有复选框将值作为数组提交,我将如何转换如下内容:
Array
(
[days] => Array
(
[Monday] => 0
[Tuesday] => 1
[Wednesday] => 0
[Thursday] => 0
[Friday] => 0
[Saturday] => 0
[Sunday] => 0
)
)
…像0b0100000
这样的位值,再次使用按位运算符?
如果有人能为我指明开始使用 PHP 中的位值的正确方向,我将不胜感激!
您可以存储所选日期的十进制值。所以作为一个非常基本的例子:
/**
* 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"])));
希望这会把你推向正确的方向。