奇怪而混乱的PHP语法

时间:2016-07-12 03:14:04

标签: php

我正在接管一个旧网站的维护,并且遇到了这种令人困惑的语法,用于处理我以前从未见过的表单,而且我不确定它的作用:

rspec foo.rb

"和"抛弃我 - 我把它读作"如果设置变量将其转换为htmlentities,但为什么会出现"和#34;在那里?

最后一行是做什么的?

foreach (array('address','comments','country','email','mail_content','name','title') as $vuln) 
{
    isset($_REQUEST[$vuln]) and $_REQUEST[$vuln] = htmlentities($_REQUEST[$vuln]);
    isset($_GET[$vuln]) and $_GET[$vuln] = htmlentities($_GET[$vuln]);
    isset($_POST[$vuln]) and $_POST[$vuln] = htmlentities($_POST[$vuln]);
    isset($$vuln) and $$vuln = htmlentities($$vuln);
}

4 个答案:

答案 0 :(得分:7)

它以不寻常的方式使用PHP的operator precedence规则。

如果您有and语句,如果左侧为假,PHP将停止处理它 - 不需要检查右侧,因为它不会产生影响到最后的结果。 (如果左侧是真的话,对or语句也是如此。)

所以写这篇文章的程序员用它作为简写:

if (isset($_REQUEST[$vuln])) {
    $_REQUEST[$vuln] = htmlentities($_REQUEST[$vuln]);
}

他们节省了少量的打字,但代价是使代码难以阅读。使用isset确保在使用数组值之前设置数组值是一种很好的做法,这就是检查的原因。

至于最后一行;从逻辑上讲,它与上述相同,但使用variable variable。第一次,$vuln将被设置为数组中的第一个项目,即address - 最后一行代码正在检查是否有一个名为{{1}的变量如果是,请将其值设置为$address

代码正在做什么。 为什么检查REQUEST,GET和POST是否超出我的范围。

答案 1 :(得分:2)

isset($var) and <statement goes here that uses $var>;

如果<statement ...>之前的语句(在这种情况下为and)评估为isset($var),则基本上只执行true。发生这种情况是因为如果在and之前有任何错误,则无需评估(或执行)其余内容。这类似于:

if (false && condition) { ... }

永远不会评估condition,因为无论其值如何评估,if条件将始终评估为false

第一个示例的更具可读性的替代方案:

if (isset($var)) {
   <statement goes here that uses $var>;
}

正如@ chris85的评论所指出,请参阅$$variable

变量变量的一个例子:

$vuln = 'abc';  /* Regular variable assignment */
$$vuln = 'def'; /* This is "equivalent" to $abc = 'def'
                 * because $$vuln expands to $<contents of $vuln>,
                 * therefore $abc is assigned with 'def'.
                 */

/* $abc is now a variable with 'def' as its value */

答案 2 :(得分:2)

嗨这些只是短形式。

angular.js:12373
XMLHttpRequest cannot load 
file:///.../codingstuff/conFusion/app/dishdetail.html. 
Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https, chrome-extension-resource.

以上行意味着

 isset($_REQUEST[$vuln]) and $_REQUEST[$vuln] = htmlentities($_REQUEST[$vuln]);

同样,if(isset($_REQUEST[$vuln])){ $_REQUEST[$vuln] = htmlentities($_REQUEST[$vuln]); } $$vuln reference,如果设置了参考variable,则会检查它是否相同

答案 3 :(得分:2)

对于通过数组的第一次迭代,可能更容易理解如下:

{{1}}

在我看来,遗留代码可能是“注册全局变量”打开时“魔法引用”的替代(或者可能除此之外)。可能是因为他们可以在数据库插入和/或页面回声之前对变量进行一些伪转义。