我正在尝试将一些PHP 5.3代码转换为PHP 5.2(不支持匿名函数)。这是PHP 5.3代码:
$nr = 2;
$a = array(1,2,3,4,5,6,7,8,9,10);
$a = array_filter($a,function($e) use($nr) {
return $e % $nr == 0;
});
我的转换是这样的:
array_filter($a,create_function('$e','return $e % $nr == 0;'));
use($nr)
应放在哪里?
答案 0 :(得分:3)
<?php
$nr = 2;
$a = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
$a = array_filter($a, create_function('$e', '
global $nr;
return $e % $nr == 0;
'));
var_dump($a);
这有效地为我们带来了JavaScript风格&#34;访问只有一个变量的副本,并且对该变量的任何写入都将在其他地方被看到:
<script> // javascript code:
var a = 1;
(function(){
a = 2;
})();
console.log(a); // javascript shows 2
</script>
但是,请注意&#34; JavaScript样式&#34;提供的功能。访问与use
不同,因为use
copies the values when the function is defined。这意味着通过use
,有多个变量副本,修改一个不会影响另一个:
<?php
$a = 1;
call_user_func(function()use($a){
$a = 2;
});
var_dump($a); // php shows 1
要实现此功能(以便我们可以执行&#34;完美的垫片&#34;),必须确保不为全局化变量分配新值。如果需要为变量分配新值,
如果您需要修改原始值,可能需要先创建它的副本,然后全局化该副本。这样,您的原始值不受限制且可以修改:
<?php
$nr = 2;
$nr_copy = 2;
$a = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
$nr = 3; // you can freely modify $nr because the function below is using $nr_copy
$a = array_filter($a, create_function('$e', '
global $nr_copy;
return $e % $nr_copy == 0;
'));
var_dump($a);
请注意,如果您需要引用的变量位于函数范围内,则选项1(global
)不起作用:
<?php
some_function();
function some_function(){
$nr = 2;
$a = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
$a = array_filter($a, create_function('$e', '
global $nr; // this will not work because $nr is undefined
return $e % $nr == 0;
'));
var_dump($a);
}
对于此类情况,您别无选择,只能使用选项2.
<?php
some_function();
function some_function(){
$nr = 2;
$a = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
$a = array_filter($a, create_function('$e', '
return $e % '.$nr.' == 0;
'));
var_dump($a);
}
如果简单连接不起作用(例如对于数组和对象),唯一的选择是序列化:
<?php
some_function();
function some_function(){
$nr = 2;
$a = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
$a = array_filter($a, create_function('$e', '
return $e % unserialize(\''.str_replace("'", "\'", serialize($nr)).'\') == 0;
'));
var_dump($a);
}
这个想法只是将变量转换为可以在函数体中插入的字符串。
答案 1 :(得分:2)
PHP 5.2不支持闭包。因此,您无法使用use
关键字。
如果你需要你的代码是5.2兼容的,你最好只创建一个命名函数/方法并传递必要的参数,而不是使用create_function
,因为后者会导致内存泄漏(创建新函数)每次和gc都没有抓住它们。)
答案 2 :(得分:0)
你可以这样使用global
:
create_function('$e','global $nr; return $e % $nr == 0;')
但是,你真的应该升级PHP,而不是担心降级:p
答案 3 :(得分:0)
您可以使用序列化/反序列化,如:
create_function('$e','return $e % unserialize(\''.serialize($nr).'\') == 0;')