有没有让这个开关语句缩短?

时间:2017-08-30 14:57:01

标签: php mysqli

  switch($act1){
     case "SUBSCRIBE":
     $error = "false";
     break;
     case "SUB & LIKE":
     $error = "false";
     break;      
     case "LIKE & COMMENT":
     $error = "false";
     break;      
     case "DISLIKE":
     $error = "false";
     break;      
     case "COMMENT":
     $error = "false";
     break;      
     case "LIKE":
     $error = "false";
     break;      
     default:
    $error = "true";
    $error_01 = "true";
    break;  
 }
 switch($act2){
     case "SUBSCRIBE":
     $error = "false";
     break;
     case "SUB & LIKE":
     $error = "false";
     break;      
     case "LIKE & COMMENT":
     $error = "false";
     break;      
     case "DISLIKE":
     $error = "false";
     break;      
     case "COMMENT":
     $error = "false";
     break;      
     case "LIKE":
     $error = "false";
     break;      
     default:
    $error = "true";
    $error_02 = "true";
    break;      
 }

switch($act3){
     case "SUBSCRIBE":
     $error = "false";
     break;
     case "SUB & LIKE":
     $error = "false";
     break;      
     case "LIKE & COMMENT":
     $error = "false";
     break;      
     case "DISLIKE":
     $error = "false";
     break;      
     case "COMMENT":
     $error = "false";
     break;      
     case "LIKE":
     $error = "false";
     break;      
     default:
    $error = "true";
    $error_03 = "true";
    break;      
 }

 switch($act4){
     case "SUBSCRIBE":
     $error = "false";
     break;
     case "SUB & LIKE":
     $error = "false";
     break;      
     case "LIKE & COMMENT":
     $error = "false";
     break;      
     case "DISLIKE":
     $error = "false";
     break;      
     case "COMMENT":
     $error = "false";
     break;      
     case "LIKE":
     $error = "false";
     break;      
     default:
    $error = "true";
    $error_04 = "true";
    break;  
 }

如何让整个事情更短?我的意思是我尝试使用for循环,但是我遇到了很多问题,因为我在这方面都很新。我希望有人能在这里帮助我。你还认为有一种更好的valadation形式,我想检查用户提供的数据是否与表格提供的选项相同,所以他不能提交表格不提供的内容。包含,以防止mysqli注射。所有这些对我来说都非常不合适,而且不是很安全。

6 个答案:

答案 0 :(得分:2)

是的,你可以把它写得更短,因为除了默认设置之外,你的所有动作都是相同的。

考虑以下情况,我重构了你的第一个switch语句,这将与以前完全相同。

switch($act1){
    case "SUBSCRIBE":
    case "SUB & LIKE":     
    case "LIKE & COMMENT":   
    case "DISLIKE":  
    case "COMMENT": 
    case "LIKE":
        $error = "false";
        break;      
    default:
        $error = "true";
        $error_01 = "true";
        break;  
}

更加动态

根据安德鲁·安德鲁发布的内容,一种更加动态的方式来看待这个问题,你可以使用循环来遍历所有行为并检查它们是否有错误。

PHP是一个很棒的工具,可以创建动态脚本,允许您不要手动重复这么多代码,并且可以自动处理您所处的情况,可能无需将来编写代码。以下是我将如何处理你的情况

    //declare a whitelist of things that should not produce an error
    $whiteList = [
        'SUBSCRIBE',
        'SUB & LIKE',
        'LIKE & COMMENT',
        'DISLIKE',
        'COMMENT',
        'LIKE',
    ];

    //add all of the acts to an array to loop over
    $acts = [$act1, $act2, $act3, $act4];

    //by default error is set to false
    $error = "false";

    foreach($acts as $key => $act) {
    //if key is less than 9, add a 0 to the front, to get error_01, error_02 etc, if its above 9 then just add the number itself like error_10
    $errorKey = $key < 9? "0{$key}" : $key;

    //check if value from act is in the whitelist declared above, if its not, set `$error` to true and set `$error_*` (with key) to "true" as well.
    if(!in_array($act, $whiteList)) {
        $error = "true";
        ${"error_$errorKey"} = "true";
    }
}

这种方式是动态的,因为您可以向$acts数组添加更多动作,它会根据数组中显示的位置自动设置error_##

问题:检查错误

稍后重新获取此错误将是一件非常困难的事情,因为您不知道设置了哪个错误或任何错误。因此,为了解决这个问题,您可以完全废弃$error_##部分,只使用$error作为变量。

//declare a whitelist of things that should not produce an error
$whiteList = [
    'SUBSCRIBE',
    'SUB & LIKE',
    'LIKE & COMMENT',
    'DISLIKE',
    'COMMENT',
    'LIKE',
];

//add all of the acts to an array to loop over
$acts = [$act1, $act2, $act3, $act4];

//by default error is set to false
$error = "false";

foreach($acts as $key => $act) {
    //check if value from act is in the whitelist declared above, if its not, set `$error` to true and set `$error_*` (with key) to "true" as well.
    if(!in_array($act, $whiteList)) {
        $error = "true";
    }
}

答案 1 :(得分:2)

另一种方法。

<?php
// allowable keywords
$whiteList = [
    'SUBSCRIBE',
    'SUB & LIKE',
    'LIKE & COMMENT',
    'DISLIKE',
    'COMMENT',
    'LIKE',
];

// if $act1 is in the list of allowable keywords then set $error = "false"
if (in_array($act1, $whiteList)) {
    $error = "false";
} else {
    $error = "true";
    $error_01 = "true";
}

if (in_array($act2, $whiteList)) {
    $error = "false";
} else {
    $error = "true";
    $error_02 = "true";
}

...

答案 2 :(得分:2)

创建一个函数来处理相同的逻辑并在那里应用switch语句。

可以调用一个通用函数,而不是重复使用相同逻辑的相同switch语句
function getError($act_in) {
    $error = "";
    switch($act_in) {
        case "SUBSCRIBE":
        case "SUB & LIKE":     
        case "LIKE & COMMENT":   
        case "DISLIKE":  
        case "COMMENT": 
        case "LIKE":
            $error = "false";
            break;      
        default:
            $error = "true";
            break;  
    }

    return $error;
}

答案 3 :(得分:0)

这是我缩短的尝试。

    $validvals = array('SUBSCRIBE', 'SUB & LIKE', 'LIKE & COMMENT', 'DISLIKE', 'COMMENT', 'LIKE');
    $error = 'false';
    for ($i=0; $i <= 4; $i++)
    {
        if (!in_array(${"act$i"}, $validvals))
        {
            $error = 'true';
            ${"error_0$i"} = 'true';
        }
        else
        {
            ${"error_0${i}"} = 'false';
        }
    }

我应该澄清一点,我不认为这比其他建议更好,但我在读之前已经开始写它了,所以我想发布它。

答案 4 :(得分:-1)

有几种方法:

  1. 简洁的开关案例

    switch($act1){
        case "SUBSCRIBE":
        case "SUB & LIKE":     
        case "LIKE & COMMENT":   
        case "DISLIKE":  
        case "COMMENT": 
        case "LIKE":
            $error = "false";
            break;      
        default:
            $error = "true";
            $error_01 = "true";
            break;  
        }
    
  2. 如上所述进行循环

  3. 创建这些字符串的TRIE并在此TRIE中搜索。如果word存在,则将error设置为false,否则将其设置为true

  4. 在SqlInjection上,始终使用参数并避免动态查询。这将照顾SqlInjection

答案 5 :(得分:-3)

烨, 你可以允许真正的开关,并在这种情况下制造条件

switch(true){
     case ($act1=='SUBSCRIBE' and $act2=='SUBSCRIBE' and .....):
     $error = "false";
     break;
     case ($act1=='SUB & LIKE' and $act2=='SUB & LIKE' and .....):
     $error = "false";
     break;      
     case ($act1=='LIKE & COMMENT' and $act2=='LIKE & COMMENT' and .....):
     $error = "false";
     break;      
     case ($act1=='DISLIKE' and $act2=='DISLIKE' and .....):
     $error = "false";
     break;      
     case ($act1=='COMMENT' and $act2=='COMMENT' and .....):
     $error = "false";
     break;      
     case ($act1=='LIKE' and $act2=='LIKE' and .....):
     $error = "false";
     break;      
     default:
    $error = "true";
    $error_01 = "true";
    break;  
 }