I got asked to write a little PHP script that takes some POSTed input from a few drop down boxes which give some selectable criteria and at the end, spits out one or more string variables containing unique codes.

The variable names are of the form $thingPlaceType, and each one is unique. The drop down boxes allow for selection of:

  • either one "thing" or all "things" together
  • either one "place" or all "places" together
  • either one "type" or all "types" together

I can't figure out how to select these codes without resorting to nested switch statements where I do

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;
            ...
      ...
  ...
}

It seems that the code is turning into the Arrow Anti-Pattern. I'm thinking I could possibly do something using multi-dimensional arrays, or maybe a single array where I match the values against the keys. But I feel that's clutching at straws and there must be something I'm missing. Is it time to turn the strings into proper objects with properties?

有帮助吗?

解决方案

if you want to convert them to objects.. you can create this.

  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();
    }

其他提示

You need to re-factor your code into functions. For example:-

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

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

I'm sure you get the idea. You can have further switch blocks in the functions if you wish, this will avoid your anti-pattern and make your code easier to understand.

Well, if you can find a way to avoid people compromising your site - perhaps by using prefixes on the target variable names, then you might be able to do this:

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

$evaluatedVariable = $$variableName;

These are called 'variable variables'. Probably I'll get flamed for using them, but I've found them useful in the past if you can use them responsibly.

Of course, this wouldn't directly work for your 'alltypes' case. You could use the suggestion to refactor into functions

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top