你好,我正在写一篇文章,允许绕过只允许base_convert的过滤器,但我最近发现,当我们在php中编写这种语法时:
"system"("id")
函数被解释,你对此有技术上的解释吗?
谢谢你!
PHP中的函数不是一等对象。这是什么意思?当你想传递函数时,例如作为array_map
的回调,你不能像这样传递函数本身:
function my_callback() { ... }
array_map(my_callback, $some_array)
my_callback
在这里被解释为一个常量,除非它存在,否则就是一个空字符串。(这在函数是第一类对象的其他语言中也适用。)只能通过名称传递函数,这意味着传递一个包含函数名称的字符串:
array_map('my_callback', $some_array)
PHP将查找全局注册的名为"my_callback"并使用它。
这意味着在array_map
内部,它必须看起来像这样:
function array_map($callback, $array) {
$callback($array); // let's ignore the "mapping" part…
}
因此,一个变量可以保存函数的名称,并且"调用";保存函数名的变量实际上调用了该函数。
现在,我们知道变量也可以被替换为相同值的字面量:
$a = 1;
$b = 2;
$c = $a + $b;
等于:
$c = 1 + 2;
对于调用-string -with-names-of-functions也是如此:
'my_callback'($array)
注意,这只适用于PHP 7,其中PHP解析器得到了巨大的改进。在此之前,$f()
是一种特殊情况的hack,但是PHP 7+解析器正确地遵循了variable-is-substitutable-by-literal逻辑。