高效的 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 循环的主要内容,如果未能解决你的问题,请参考以下文章