2012-05-25 41 views
4

我被要求編寫一個PHP腳本,它從幾個下拉框中提取一些POST輸入,這些下拉框提供了一些可選擇的條件,並在最後吐出一個或多個包含唯一代碼的字符串變量。如何替換嵌套的開關語句

變量名稱的形式爲$ thingPlaceType,每一個都是唯一的。下拉框允許的選擇:

  • 任何一個「東西」或所有「東西」一起
  • 任何一個「地方」或所有的「地方」一起
  • 任何一個「類型」或全部「種」起來

我無法弄清楚如何選擇這些代碼,而不訴諸嵌套switch語句,我做

switch($_POST['thing']) 
{ 
    case "thing1": 
    switch($_POST['place']) 
    { 
     case "place1": 
      switch($_POST['type']) 
      { 
      case "type1": 
       $output = $thing1Place1Type1; 
      case "type2": 
       $output = $thing1Place1Type2; 
      case "alltypes": 
       $output = $thing1Place1Type1.$thing1Place1Type2.$thing1PlaceType3; 
      } 
     case "place2": 
     ... 
     case "allplaces": 
     ... 
     } 
    case "thing2": 
    switch($_POST['place']) 
    { 
     case "place1": 
      switch($_POST['type']) 
      { 
      case "type1": 
       $output = $thing1Place1Type1; 
      ... 
     ... 
    ... 
} 

似乎代碼正在變成箭頭反模式。我在想我可能會使用多維數組做一些事情,或者可能是一個單一的數組,我將這些值與鍵匹配。但我覺得這是抓着吸管,一定有我失蹤的東西。現在是時候把字符串變成具有屬性的適當對象嗎?

+1

像'$ thing1Place1Type1'這些變量 - 這只是僞代碼,還是你真的需要評估一個變量名? –

+1

任何時候當你有一堆名字非常相似的變量時,你很可能需要重新評估你的設計。例如。 '$ thing1place1','$ thing1place2'等等非常自然地映射到例如'$ things_places = array(1 => array(1 =>'some place',2 =>'another place'),2 => ...);'(或者你也可以使用明確的鍵名,例如'''位置'=>數組(1 => ...)')。轉向更明智的數據模型,你會發現這樣的問題更容易管理,如果不是不存在的話。 –

回答

2

如果你想將它們轉換爲對象..你可以創建它。

class Object { 
     private $thing; 
     private $place; 
     private $type; 

     public function __construct() { 
      $this->thing = $_POST['thing']; 
      $this->place = $_POST['place']; 
      $this->type = $_POST['type']; 

      $this->processThing($this->thing, $this->place, $this->type); 
     } 

     public function processThing($thing = false, $place = false, $type = false) { 
       //noW that you have all the properties you just need just process it 
     } 

    } 

    if(isset($_POST['thing']) && isset($_POST['place']) && isset($_POST['type'])) { 
     $object = new Object(); 
    } 
+0

這最接近我最後要做的事情。我構建了對象,並從變量名稱本身獲取了Thing,Place,Type屬性。然後實際上只需做一些'if($ thing && $ place && $ type)'語句就容易多了。 – Biggles

+0

這看起來像我用來編寫自動填充XML模式的函數的邏輯。你可能只是把我放在一個頁面功能的好主意。 – Imperative

3

您需要將代碼重新分解爲函數。例如: -

switch($_POST['thing']) 
{ 
    case "thing1": 
     $result = processThings($thing1); 
     break; 
    case "thing2": 
     $result = processThings($thing2); 
     break; 
} 

function processThings($thing) 
{ 
    //processing code goes here 
} 

我相信你明白了。如果您願意,您可以在函數中使用更多的開關塊,這樣可以避免您的反模式,並使您的代碼更易於理解。

+0

這有幫助,但之後它仍然是一個幾乎不可維護的混亂,所以我不得不重寫整個部分。 – Biggles

+0

@Biggles也看看這個答案了。 http://stackoverflow.com/a/106482/212940 – vascowhite

0

好吧,如果你能找到一種方法,避免人影響你的網站 - 通過對目標變量名稱前綴或許,那麼你也許可以做到這一點:

$variableName = "A prefix_".$_POST['thing'].$_POST['type'].$_POST['place']; 

$evaluatedVariable = $$variableName; 

這些被稱爲「可變變量。也許我會因爲使用它們而發火,但如果你能夠負責任地使用它們,我發現它們在過去很有用。

當然,這不會直接適用於您的'alltypes'情況。你可以使用這個建議來重構功能

+0

這非常不安全,並且一個不好的建議。如果在使用之前添加了if(in_array($ _ POST ['thing'],array(「thing1」,「thing2」))){..}',它可能不會那麼多。 – SuperSaiyan

+0

是的,這可以工作 - 這是前綴的原因,當然 - 它限制了可能被評估的變量 –

+0

Upvoted this。我確實嘗試了一些想法,因爲我可以很容易地驗證輸入以確保它是安全的(再加上它不是面向web的)。然而,由於「全部」選擇​​而變得複雜。 – Biggles