缩短代码、ORDER BY和SWITCH


Shortening of code, ORDER BY and SWITCH

你能帮我缩短代码吗。重点是,我想根据给定的$T以不同的顺序从数据库中获取数据。知道吗?

public function rewriteQuery($T){
switch ($T) {
    case 0:
        $query="SELECT id, title FROM kshome WHERE del=0 AND active=1 ORDER BY FIELD(id,1,2,3,4,5,6)";  
        break;
     case 1:
        $query="SELECT id, title FROM kshome WHERE del=0 AND active=1 ORDER BY FIELD(id,2,3,4,5,6,1)";  
        break;
     case 2:
        $query="SELECT id, title FROM kshome WHERE del=0 AND active=1 ORDER BY FIELD(id,3,4,5,6,1,2)";    
        break;
     case 3:
       $query="SELECT id, title FROM kshome WHERE del=0 AND active=1 ORDER BY FIELD(id,4,5,6,1,2,3)";  
        break;
     case 4:
      $query="SELECT id, title FROM kshome WHERE del=0 AND active=1 ORDER BY FIELD(id,5,6,1,2,3,4)";  
        break;
    default:
       $query="SELECT id, title FROM kshome WHERE del=0 AND active=1 ORDER BY FIELD(id,6,1,2,3,4,5)";  
    break;
    }        
  return $query;             
} 

缩短这一时间的一种方法是创建一个返回order by字段的数组。

类似这样的东西:

$order_by_array = array(
  0 => "(id,1,2,3,4,5,6)", 
  1 => "(id,2,3,4,5,6,1)", 
  2 => "(id,3,4,5,6,1,2)", 
  3 => "(id,4,5,6,1,2,3)", 
  4 => "(id,5,6,1,2,3,4)"
);

然后您的rewriteQuery($T)函数可以重写为:

public function rewriteQuery($T){
  $order_by = "(id,6,1,2,3,4,5)"; // Default
  if (array_key_exists($T, $order_by_array)) {
    $order_by = $order_by_array[$T];
  }
  $query = "SELECT id, title FROM kshome WHERE del=0 AND active=1 ORDER BY FIELD{$order_by}";
  ...
}

除了在构造查询字符串时消除冗余之外,我看不到还有什么可以缩短的:

public function rewriteQuery($T){
$query = "SELECT id, title FROM kshome WHERE del=0 AND active=1 ORDER BY FIELD";
switch ($T) {
    case 0:
        $query.="(id,1,2,3,4,5,6)";  
        break;
     case 1:
        $query.="(id,2,3,4,5,6,1)";  
        break;
     case 2:
        $query.="(id,3,4,5,6,1,2)";    
        break;
     case 3:
       $query.="(id,4,5,6,1,2,3)";  
        break;
     case 4:
      $query.="(id,5,6,1,2,3,4)";  
        break;
    default:
       $query.="(id,6,1,2,3,4,5)";  
    break;
    }        
  return $query;             

虽然我更喜欢其他答案,以防您的订购是固定的,但这里有一个更灵活的解决方案:

function rewriteQuery($T) {
    $query = "SELECT id, title FROM kshome WHERE del=0 AND active=1 ORDER BY FIELD(id,";
    $order = array("1", "2", "3", "4", "5", "6");
    if($T < count($order)) {
        for($i = $T, $end = false;;$i++) {
            if($i == count($order)) {
                $i = 0;
                $end = true;
            }
            if($end && $i == $T) {
                break;
            }
            $query .= $order[$i] . ",";
        }
        $query = substr($query, 0, -1) . ")";
        return $query;
    } else {
        return "ERROR";
    }
}
$index = 5;
echo rewriteQuery($index);

请参阅PHP iddle。

基本上,你必须意识到你的$T只不过是你想要开始你的订单的索引(把你的订单作为一个数组)。一旦意识到这一点,您就可以实现以下逻辑:
$T为起点,我们遍历数组,直到到达终点,然后将$i设置为零,并激活一个结束条件以不运行无限循环。CCD_ 7将继续再次增加,直到其达到CCD_。剩下的就是去掉后面的,。我只是用)替换它来完成查询。

好吧,如果你想变得特别可怕,你可以计算整个事情:

public function rewriteQuery($T){
  $num_cols = 6;
  // Build a naughty little array to pick numbers from.
  $numbers = array_merge(range(1, $num_cols, 1), range(1, $num_cols, 1));
  // Pick the section from the array corresponding to our $T
  $rotated = array_slice($numbers, $T, $num_cols);
  // Shove "id" on the front
  array_unshift($rotated, 'id');
  // Build a string
  $final_list = implode(", ", $rotated);
  // Build the SQL
  $query = "SELECT id, title FROM kshome WHERE del = 0 AND active = 1 ORDER BY FIELD($final_list)";
  return $query;
}

但坦率地说,我真的不认为你所做的有什么错。按照其他答案的建议,将排序字符串从主查询中分离出来,可以防止在主查询发生更改时不得不更改大量行,这是很好的。

这个想法是在复制和粘贴代码之间找到一个愉快的平衡,这很难维护,而代码太聪明了,当你在三周后回到它时,你不会理解它。我总是偏向前者。

我的意思是:不要把这个答案当回事——这只是一个例子,说明如果你在"我永远不能含糊地重复我自己"的道路上走得太远,你在可读性和可维护性方面会错到什么程度

好的,我知道你希望代码简短,但为了防止需要大量开关,你可以尝试循环而不是手动数组,因为你的订单有很好的模式。

public function rewriteQuery($T)
{
    $query = "SELECT id, title FROM kshome WHERE del=0 AND active=1 ORDER BY FIELD";
    $fieldOrder =" (id, ";
    $j = $T;
    $i=1;
    if($j > 0 && $j < 5)    // or whatever you wish
    {   
        while(1)
        {   // replace 6 (below) by whatever your limit is
            $fieldOrder .= ($j % 6) + 1;
            if($i < 6)
                $fieldOrder .= ", ";
            else
                break;
            $j++; $i++;
        }
    }
    else
    {   $fieldOrder .= "6, 1, 2, 3, 4, 5"; 
        // or maybe a loop again! :-D
    }
    $fieldOrder .= " )";
    return($query.$fieldOrder);
}