I'm trying to convert some PHP 5.3 code into PHP 5.2 (which doesn't support anonymous functions) . This is the PHP 5.3 code:
$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;
});
My conversion is as such:
array_filter($a,create_function('$e','return $e % $nr == 0;'));
Where should the use($nr)
be placed?
global
will work fine actually:
<?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);
This effectively gives us "JavaScript style" access whereby there's only one copy of the variable, and any writes made to that variable will be seen everywhere else:
<script> // javascript code:
var a = 1;
(function(){
a = 2;
})();
console.log(a); // javascript shows 2
</script>
However, note that the functionality provided by "JavaScript style" access differs from use
, because use
copies the values when the function is defined. This means that via use
, there are multiple copies of the variables and modifying one would not affect the other:
<?php
$a = 1;
call_user_func(function()use($a){
$a = 2;
});
var_dump($a); // php shows 1
To achieve this functionality (so that we can do a "perfect shim"), you must ensure that you do not assign new values to the globalized variables. If you need to assign new values to the variables,
If you need to modify your original value, you may want to first create a copy of it, and then globalize that copy. This way, your original value is not bounded and can be modified:
<?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);
Note that Option 1 (global
) doesn't work if the variable you need to refer to is within a function's scope:
<?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);
}
For such cases, you have no choice but to use Option 2.
You can superimpose the value directly into the function's definition:
<?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);
}
In cases where simple concatenation don't work (e.g. for arrays and objects), the only option is serializing:
<?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);
}
The idea is simply to convert the variable into a string that you can insert within the function body.
PHP 5.2 doesn't support Closures. Hence, you can't use the use
keyword.
If you need your code to be 5.2 compatible, you would be better off just creating a named function/method and pass in the necessary parameters rather using create_function
as the latter can cause memory leaks (new function is created each time and gc doesn't catch them all).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With