【问题标题】:Is there a way to simplify this case statement?有没有办法简化这个案例陈述?
【发布时间】:2011-10-12 16:47:39
【问题描述】:

我有这个 PHP 案例声明

switch ($parts[count($parts) - 1]) {
    case 'restaurant_pos':
        include($_SERVER['DOCUMENT_ROOT'] . '/pages/restaurant_pos.php');
        break;
    case 'retail_pos':
    include($_SERVER['DOCUMENT_ROOT'] . '/pages/retail_pos.php');
        break;  
    .....

}

这很好用,但我有很多文件(比如 190 个),我很想知道是否有办法让这个案例陈述与任何东西一起工作,所以我不必做 190 个案例条件。我在想我可以在这种情况下使用条件,也许看看该文件是否存在,如果存在,则显示,如果不存在,则可能是 404 页面,但我不确定这样做的好方法......任何想法都会有所帮助很多

【问题讨论】:

    标签: php loops directory switch-statement


    【解决方案1】:

    这是一个没有安全检查的简单实现:

    $file=$_SERVER['DOCUMENT_ROOT']."/pages/".$parts[count($parts) - 1].".php";
    if(file_exists($file)) include $file;
    else show404();
    

    例如,为了使其更安全,您可以从 $parts[count($parts) - 1] 中删除斜杠

    【讨论】:

    • 正如我所说,我没有编写安全检查,但您可以删除斜杠或双点
    • 我会在示例中添加安全检查后立即投票。
    【解决方案2】:

    为什么不这样呢?

    $include_file = $_SERVER['DOCUMENT_ROOT'] . '/pages/' . $parts[count($parts) - 1] . '.php';
    
    if (file_exists( $include_file ))
    {
        include( $include_file );
    }
    

    【讨论】:

      【解决方案3】:

      如果不是用户输入,你可以这样做

      $include = $parts[count($parts) - 1];
      if ($include) {
          if (file_exists($_SERVER['DOCUMENT_ROOT'] . '/pages/'.$include.'.php')){
                include $_SERVER['DOCUMENT_ROOT'] . '/pages/'.$include.'.php';
          }
      }
      

      重复,如果 $include 是从用户输入中填充的,请不要这样做!

      【讨论】:

      • 你确定file_exists($include)?它只是路径的一部分。它永远是false
      【解决方案4】:
      if (file_exists($path = $_SERVER['DOCUMENT_ROOT'].'/pages/'.$parts[count($parts) - 1].'.php')
      {
          include $path;
      }
      

      【讨论】:

        【解决方案5】:

        检查文件是否存在,然后包含它。

        请注意,如果这是用户输入,您必须验证 $page 的内容以确保它不包含像 /../../../../ 这样的路径来尝试读取文件系统上的其他位置。

        例如,如果您知道所有路径都是带有下划线的字母数字,您可以这样做:

        $page = $parts[count($parts)] - 1;
        
        if (preg_match('/^[A-Z0-9_]+$/i', $page)) {
          // it's okay, so include it.
          if (file_exists($_SERVER['DOCUMENT_ROOT'] . "/pages/$page.php") {
            include($_SERVER['DOCUMENT_ROOT'] . "/pages/$page.php");
          }
        }
        

        【讨论】:

        • 第二个 if 语句执行 preg_match ...应该在 $page = $parts[count($parts)] - 1; 之前或之后,它究竟在验证什么
        • @Tamer 把if () 放在preg_match() if () 里面我会修改上面的答案。
        【解决方案6】:

        您可以在数组中预定义文件名,然后使用in_array 来检查名称是否存在:

        $files = array('restaurant_pos', 'retail_pos', ......);
        $file = $parts[count($parts) - 1];
        if (in_array($file, $files)) {
            include($_SERVER['DOCUMENT_ROOT'] . "/pages/$file.php");
        }
        

        【讨论】:

        • 白名单是个好概念,但手动维护 190 个条目(很可能会改变)至少很麻烦。最好在 pages/ 目录上使用 scandir() 构建白名单,并将该目录用作白名单本身。
        • 你将如何使用 scandir() 构建该白名单
        • @Tamer 您可以在 scandir() 的输出上应用 array_filter()。
        【解决方案7】:

        另一种方法是检查给定文件是否真的存在于特定目录中:

        $file = $_SERVER['DOCUMENT_ROOT'] . '/' . basename($parts[count($parts) - 1]) . '.php';
        if (is_file($file)) include($file);
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2015-04-26
          • 2019-09-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-06-13
          • 2021-06-22
          相关资源
          最近更新 更多