高效的 if 语句 / for 循环

Posted

技术标签:

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

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

    在这段代码中,有没有办法合并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";
      
    
    

    目前,我做的相当标准的事情是将我的 $_POST 数组从表单提交中拆分出来,“清理”内容并将元素存储在单个变量中:

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

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

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

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

【问题讨论】:

【参考方案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) 的讨论很有趣;实际上,我从 ***.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() 了吗?

【讨论】:

以上是关于高效的 if 语句 / for 循环的主要内容,如果未能解决你的问题,请参考以下文章

高效开发:Shell 流程控制

高效开发:Shell 流程控制

Java条件语句

裁剪的高效霓虹灯实现

如何让 Python 中的 for 循环更高效

高效更新 SQL,一条 SQL 语句更新多行,避免循环