有效的if语句/for循环


Efficient if statement / for loop

两个简短的问题,基于试图提高我的代码效率(我认为我的最终目标是使我的整个(相当复杂的)网站基于某种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循环中动态生成所有变量?(我知道当人们问他们是否可以动态生成变量时,标准答案是使用哈希图或类似的方法,但我很想看看是否有我错过的技术)

您可以使用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));

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

你为什么要合并这个,这只会让代码更难阅读。如果您的代码需要if,然后需要for循环,那么显示这个事实,这并没有什么不好的。如果你想让代码更可读,那么你可以写一个函数,用一个合适的名字,例如listAttachedFiles()

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

输入验证转义之间存在差异。验证输入是一件好事,例如,如果你期望一个数字,那么只接受数字作为输入。但是,在了解目标系统之前,不应该进行转义。因此,让输入保持原样,在写入数据库之前使用mysql_real_escape_string()函数,在写入HTML页面之前使用函数htmlspecialchars()

在需要之前组合转义函数,可能导致无效数据。在一个特定的目标系统上,它可能变得不可能正确地给出。

我个人认为,使用"If"语句的性能成本值得拥有易于阅读的代码。此外,如果有这样的方法的话,你必须确保你实际上通过组合使用更少的循环。

我不确定我是否理解你的第二个问题,但你看过extract()和array_walk()吗?

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

第2点-AaaargghhH!您应该在数据离开PHP时更改数据的表示形式,使用近似到目的地的方法,而不是在数据到达PHP时。

为了使for循环更有效率请不要在循环的条件中使用Count()。

这是他们在学校教的第一件事。因为For循环在每次迭代时都在重新评估条件。

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