Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/blackberry/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 如何替换嵌套的switch语句_Php_Nested_Switch Statement_Anti Patterns - Fatal编程技术网

Php 如何替换嵌套的switch语句

Php 如何替换嵌套的switch语句,php,nested,switch-statement,anti-patterns,Php,Nested,Switch Statement,Anti Patterns,我被要求编写一个小PHP脚本,从几个下拉框中获取一些已发布的输入,这些下拉框给出一些可选择的标准,最后,输出一个或多个包含唯一代码的字符串变量 变量名的形式为$thingPlaceType,并且每个名称都是唯一的。下拉框允许选择: 要么是一个“东西”,要么是所有“东西”加在一起 一个“地方”或所有“地方”一起 一个“类型”或所有“类型”一起 如果不使用嵌套的switch语句,我想不出如何选择这些代码 switch($_POST['thing']) { case "thing1":

我被要求编写一个小PHP脚本,从几个下拉框中获取一些已发布的输入,这些下拉框给出一些可选择的标准,最后,输出一个或多个包含唯一代码的字符串变量

变量名的形式为$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;
            ...
      ...
  ...
}

代码似乎正在变成箭头反模式。我想我可以用多维数组做一些事情,或者用一个数组来匹配键值。但我觉得这是在抓救命稻草,我肯定错过了什么。是时候将字符串转换为具有属性的适当对象了吗?

您需要将代码重新分解为函数。例如:-

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

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

我相信你明白了。如果愿意,您可以在函数中添加更多的开关块,这将避免反模式,并使代码更易于理解。

如果您可以找到一种方法来避免人们破坏您的站点,或许可以在目标变量名上使用前缀,那么您可以做到:

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

$evaluatedVariable = $$variableName;
这些被称为“变量”。也许我会因为使用它们而被激怒,但如果你能负责任地使用它们,我发现它们在过去很有用


当然,这不会直接适用于您的“所有类型”案例。如果要将函数转换为对象,可以使用建议将其重构为函数。。你可以创建这个

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

这些变量如“$thing1Place1Type1”-这只是伪代码,还是您真的需要计算一个变量名?当您有一组名称非常相似的变量时,您很有可能需要重新评估您的设计。例如,
$thing1place1
$thing1place2
,等等。非常自然地映射到例如
$things\u places=array(1=>array(1=>'某个地方',2=>'另一个地方'),2=>…)(或者您也可以使用显式键名,例如
'places'=>数组(1=>…)
)。移动到一个更合理的数据模型,你会发现这样的问题即使不存在,也更容易管理。这是非常不安全的,也是一个不好的建议。如果你在使用它之前先添加
if(在数组中($\u POST['thing'],array(“thing1”,“thing2”)){..}
,可能就没有那么多了。是的,这可能会起作用-当然,这就是前缀的原因-它限制了可能被计算的变量。我确实尝试了这样一个想法,因为我可以很容易地验证输入,以确保它是安全的(另外它也不是面向web的)。不过,由于“全部”选择,它变得复杂了。谢谢Biggles:)它有点“marmite”特性,正如人们很快指出的那样,你当然需要记住安全性。当然,这在某些情况下是有用的。这很有帮助,但之后仍然很难维护,所以我不得不重写整个部分。@Biggles也看看这个答案。这是我最后不得不做的事情。我构建了对象,并从变量名本身获得了Thing、Place和Type属性。然后,实际上只需执行几个
if($thing&&$place&&&$type)
语句就容易多了。这看起来正是我用来编写自动填充XML模式的函数的逻辑。你可能刚刚给我带来了一个关于页面功能的好主意。