【问题标题】:Efficient if statement / for loop高效的 if 语句 / for 循环
【发布时间】:2012-04-12 23:26:32
【问题描述】:

基于试图使我的代码更高效的 2 个简短问题(我认为我的最终目标是使我的整个(相当复杂的)网站基于某种 MVC 框架,但不是作为专业程序员,我认为这是可行的是一个漫长而陡峭的学习曲线..)

  1. 在这段代码中,有没有办法合并if 语句和for 循环,以避免嵌套:

    if($fileatt['name']!=null)
    {
      $attachedFiles = "You uploaded the following file(s)\n";
      for($i=0;$i<count($docNames);$i++)
      {
        $attachedFiles = $attachedFiles. " - " . $docNames[$i] . "\n";
      }
    }
    
  2. 目前,我做的相当标准的事情是将我的 $_POST 数组从表单提交中拆分出来,“清理”内容并将元素存储在单个变量中:

    $name = cleanInput($_POST['name']);
    $phone = cleanInput($_POST['phone']);
    $message = cleanInput($_POST['message']);
    ...
    

(其中cleanInput() 包含striptags()mysql_real_escape_string()

我曾认为将所有信息保存在数组中可能会使我的代码更高效,但是有没有办法将函数应用于数组的所有(或选定的)元素?例如,在 R 中,apply() 函数就是这样做的。

另外,鉴于我的所有变量与$_POST 数组中的名称相同,有没有办法在foreach 循环中动态生成所有变量? (当人们问他们是否可以动态生成变量时,我知道标准答案是使用哈希图或类似方法,但我很想看看是否有我错过的技术)

【问题讨论】:

    标签: php coding-style


    【解决方案1】:

    为了让你的 for 循环更高效不要在循环的条件中使用 Count()

    这是他们在学校教的第一件事。由于 For 循环在每次迭代中重新评估条件。

    $nbOfDocs = count($docNames); //will be much faster
    for($i=0;$i<$nbOfDocs;$i++)
    {
       $attachedFiles = $attachedFiles. " - " . $docNames[$i] . "\n";
    }
    

    【讨论】:

      【解决方案2】:

      1)对于第一个问题,如何合并if和for循环:

      为什么要合并它,它只会使代码更难阅读。如果您的代码需要 if 和之后的 for 循环,那么请展示这个事实,这并没有什么不好。如果您想让代码更具可读性,那么您可以编写一个函数,并使用合适的名称,例如listAttachedFiles().

      2)关于清理用户输入的问题:

      输入验证转义是有区别的。验证输入是一件好事,例如如果您需要一个数字,则只接受数字作为输入。但是在您知道目标系统之前,不应进行转义。所以保持输入不变,在写入数据库之前使用mysql_real_escape_string()函数,在写入HTML页面之前使用函数htmlspecialchars()

      在需要之前组合转义函数可能会导致无效数据。在某个目标系统上,可能无法正确地给出它。

      【讨论】:

      • 谢谢 - 我想这就是我认为 1) 的答案。关于 2) 的讨论很有趣;实际上,我从 stackoverflow.com/a/544302/889604 的清理功能中获得了灵感——我一直认为最好尽快清理输入,尽管您和 @symcbean 都说这不一定正确
      • @ChrisW - 是的,编写这样一个“做一次就忘记”函数很诱人,但你可以/将会陷入困境。因为很难永远忘记转义,所以您可以在目标系统周围编写一个包装器来处理转义。 PHP 的PDO 库就是这样一个数据库访问的包装器。
      【解决方案3】:

      您可以使用extract 并将其与array_map 结合使用

      extract(array_map('cleanInput', $_POST), EXTR_SKIP);
      
      echo $name; // outputs name
      

      请注意 $_POST could be 任何东西,然后用户可以向您的服务器提交任何东西,它会成为您代码中的变量,因此如果您有类似的东西

      if(empty($varName)) { } // assumes $varName is empty initially
      

      用户提交$_POST['varName'] = 1可以轻松绕过

      为避免此类事故,您可以设置一个数组白名单并仅过滤掉您需要的那些:

      $whitelist = array('name', 'phone', 'message');
      $fields = array();
      
      foreach($_POST as $k => $v) {
         if(in_array($k, $whitelist)) $fields[$k] = $v;
      }
      
      extract(array_map('cleanInput', $fields));
      

      【讨论】:

      • OMG - 你应该总是使用extract的前缀!
      • 谢谢 - 这很有趣。我一定会结合其他受访者提出的观点使用它
      【解决方案4】:

      第 1 点是过早优化。并且您希望通过这样做获得更好的性能/可读性。 (类似于对所有事物使用数组)。

      第 2 点 - 啊啊啊啊啊!您应该在数据离开 PHP 的点更改数据的表示,使用方法 approporiate 到目的地 - 而不是它到达的地方PHP。

      【讨论】:

        【解决方案5】:

        我个人认为使用“If”语句的性能成本值得拥有易于阅读的代码的好处。如果有这种方法,您还必须确保通过组合实际使用更少的周期。

        我不确定我是否遵循了您的第二个问题,但是您看过 extract() 和 array_walk() 了吗?

        【讨论】:

          猜你喜欢
          • 2018-11-23
          • 1970-01-01
          • 2013-02-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-08-06
          相关资源
          最近更新 更多