通知偏好困境

时间:2010-08-02 19:43:55

标签: php arrays if-statement

我正在构建一个页面,允许我们的成员根据许多选项选择他们的通知首选项。例如,我为成员提供选项,以便在新邮件到达时以及发生更新时选择通知。他们可以通过电子邮件,短信,两者或两者都收到通知。

如果我只是简单地构建它:

HTML代码

<tr>
    <td>Alert me when a new message comes in:</td>
</tr>
<tr>
    <td>
       <label><input name="ENREME" type="radio" style="margin-left:30px;" value="EMAIL" <?php if ($smscode == "7" || $smscode == "4") { ?>checked="checked"<?php } ?> tabindex="15" />Email</label>
       <label><input name="ENREME" type="radio" style="margin-left:30px;"  value="SMS" <?php if ($smscode == "7" || $smscode == "5") { ?>checked="checked"<?php } ?> />SMS</label>
       <label><input name="ENREME" type="radio" style="margin-left:30px;"  value="BOTH" <?php if ($smscode == "7" || $smscode == "6") { ?>checked="checked"<?php } ?> tabindex="15" />Both</label>
       <label><input name="ENREME" type="radio" style="margin-left:30px;" value="NONE" <?php if ($smscode == "0") { ?>checked="checked"<?php } ?> />Don't notify me</label>
    </td>
</tr>
<tr>
    <td>Alert me when a new update to my site occurs:</td>
</tr>
<tr>
    <td>
       <label><input name="RECRUITEME" type="radio" style="margin-left:30px;" value="EMAIL" <?php if ($smscode == "7" || $smscode == "1") { ?>checked="checked"<?php } ?> tabindex="15" />Email</label>
       <label><input name="RECRUITEME" type="radio" style="margin-left:30px;"  value="SMS" <?php if ($smscode == "7" || $smscode == "2") { ?>checked="checked"<?php } ?> /> SMS</label>
       <label><input name="RECRUITEME" type="radio" style="margin-left:30px;"  value="BOTH" <?php if ($smscode == "7" || $smscode == "3") { ?>checked="checked"<?php } ?> tabindex="15" />Both</label>
       <label><input name="RECRUITEME" type="radio" style="margin-left:30px;" value="NONE" <?php if ($smscode == "0") { ?>checked="checked"<?php } ?> />Don't notify me</label>
    </td>
</tr>

变量编码和存储

<?php
    if ($_POST['ENREME'] == "BOTH" && $_POST['RECRUITEME'] == "BOTH") {
        $notif = 15;
    } elseif ($_POST['ENREME'] == "BOTH" && $_POST['RECRUITEME'] == "SMS") {
        $notif = 14;
    } elseif ($_POST['ENREME'] == "BOTH" && $_POST['RECRUITEME'] == "EMAIL") {
        $notif = 13;
    } elseif ($_POST['ENREME'] == "BOTH" && $_POST['RECRUITEME'] == "NONE") {
        $notif = 12;
    } elseif ($_POST['ENREME'] == "EMAIL" && $_POST['RECRUITEME'] == "BOTH") {
        $notif = 11;
    } elseif ($_POST['ENREME'] == "EMAIL" && $_POST['RECRUITEME'] == "SMS") {
        $notif = 10;
    } elseif ($_POST['ENREME'] == "EMAIL" && $_POST['RECRUITEME'] == "EMAIL") {
        $notif = 9;
    } elseif ($_POST['ENREME'] == "EMAIL" && $_POST['RECRUITEME'] == "NONE") {
        $notif = 8;
    } elseif ($_POST['ENREME'] == "SMS" && $_POST['RECRUITEME'] == "BOTH") {
        $notif = 7;
    } elseif ($_POST['ENREME'] == "SMS" && $_POST['RECRUITEME'] == "SMS") {
        $notif = 6;
    } elseif ($_POST['ENREME'] == "SMS" && $_POST['RECRUITEME'] == "EMAIL") {
        $notif = 5;
    } elseif ($_POST['ENREME'] == "SMS" && $_POST['RECRUITEME'] == "NONE") {
        $notif = 4;
    } elseif ($_POST['ENREME'] == "NONE" && $_POST['RECRUITEME'] == "BOTH") {
        $notif = 3;
    } elseif ($_POST['ENREME'] == "NONE" && $_POST['RECRUITEME'] == "SMS") {
        $notif = 2;
    } elseif ($_POST['ENREME'] == "NONE" && $_POST['RECRUITEME'] == "EMAIL") {
        $notif = 1;
    } elseif ($_POST['ENREME'] == "NONE" && $_POST['RECRUITEME'] == "NONE") {
        $notif = 0;
    }
?>

我要为16个可能的变量编写代码(从而创建超过100行代码)。任何人都可以想出一种更好的方法来整合这段代码吗?根据所做的选择,我希望结果等于一个数字(即28等于,发送新消息和更新的电子邮件和短信通知)。

创建新表或数据库并进行引用调用不是解决方案,因此请不要建议。

谢谢!

2 个答案:

答案 0 :(得分:3)

这是一个关于如何在开发简单事物时不知道C会让你陷入困境的例子。据我所知,最简单的选择是最好的,只需使用二进制!:

define('SEND_EMAIL',1);
define('SEND_SMS',2);

/* The values are packed together, low bits represent 'update' options,
 * high bits represent 'message' options
 * You can save up to 4 variants (ON/OFF) with 0xf
 */
$options = ((intval($_POST['message']) & 0xf) << 4) | (intval($_POST['update']));

...
// Retrieve options from, say, stored option
$message = ($options >> 4) & 0xf;
$update = $options & 0xf;

/* For readability, this can be a function */
if ($message == (SEND_SMS|SEND_EMAIL)) {
    $message = 'Both';
}
else if ($message == SEND_SMS) {
    $message = 'SMS';
}
else if ($message == SEND_EMAIL) {
    $message = 'Email';
}

答案 1 :(得分:1)

听起来你真正想要的是一个按位解决方案。使用位,您可以将许多布尔开关存储到单个整数中。这个答案使用了一些环形交叉口来保持清晰 - 你可以直接使用int值而不是下面显示的pow(2,X)......认为它是“教人钓鱼”。

如果你想要更多的解决方案,虽然解决方案很复杂,但请看看Ast Derek的回答。他们都做同样的事情并按照同样的原则运作。

为了存储这些,我们来做两个简单的开关:

switch($_GET['x']) {
   case 'Email': $x = pow(2,0); break; // 1
   case 'Sms':   $x = pow(2,1); break; // 2
   case 'Both':  $x = pow(2,0) + pow(2,1); break;// 3
   default: $x = 0;
}

switch($_GET['y']) {
   case 'Email': $y = pow(2,2); echo "Y Email"; break; // 4
   case 'Sms':   $y = pow(2,3); echo "Y SMS"; break; // 8
   case 'Both':  $y = pow(2,2) + pow(2,3); echo "Y Both"; break; // 12
   default: $y = 0;
}

如您所见,缺少“无”选项。没有一个只是没有电子邮件或短信。此外,Both选项不是单独的选项,而是两者的组合。

现在我们有了这些值,我们可以将这两个数字组合成一个数字,因为它们的相关位都在不同的范围内。

$z = $x | $y;

查看位时会发生以下情况 - 假设我们有X =电子邮件,Y =两者。

x = 0001 -> (0 + 0 + 0 + 1) -> 1
y = 1100 -> (8 + 4 + 0 + 0) -> 12
    -----
OR: 1101 -> (8 + 4 + 0 + 1) -> 13

这将给您带来以下可能的结果:

0: x = none, y = none
1: x = email, y = none
2: x = sms, y = none
3: x = both, y = none
4: x = none, y = email
5: x = email, y = email
6: x = sms, y = email
7: x = both, y = email
8: x = none, y = sms
9: x = email, y = sms
10: x = sms, y = sms
11: x = both, y = sms
12: x = none, y = both
13: x = email, y = both
14: x = sms, y = both
15: x = both, y = both

要检测选择了哪个,只需反转操作。

所以你可以测试一下,我把整个设置放在一个Github Gist中供你欣赏和修补:http://gist.github.com/505272

随意询问您是否需要澄清;我不确定我是否清楚地解释了它:/