PHP <5.3, create_function и использовать переменную

Я пытаюсь преобразовать код 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) ?

Solutions Collecting From Web of "PHP <5.3, create_function и использовать переменную"

Вариант 1: Глобальный доступ

global будет работать нормально: ссылка на код

 <?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-стилю», когда имеется только одна копия переменной, и любые записи, сделанные в эту переменную, будут видны везде:

 <script> // javascript code: var a = 1; (function(){ a = 2; })(); console.log(a); // javascript shows 2 </script> 

Однако обратите внимание, что функциональность, обеспечиваемая доступом «стиль JavaScript», отличается от use , поскольку use копирует значения, когда функция определена . Это означает, что с помощью use имеется несколько копий переменных, а изменение одного не повлияет на другое:

 <?php $a = 1; call_user_func(function()use($a){ $a = 2; }); var_dump($a); // php shows 1 

Чтобы достичь этой функциональности (чтобы мы могли сделать «идеальную прокладку»), вы должны убедиться, что глобальные переменные не присваивают новые значения. Если вам нужно назначить новые значения для переменных,

Если вам нужно изменить исходное значение, вы можете сначала создать его копию, а затем глобализовать эту копию. Таким образом, ваше исходное значение не ограничено и может быть изменено: ссылка на код

 <?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.


Вариант 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); } 

Идея состоит в том, чтобы просто преобразовать переменную в строку, которую вы можете вставить в тело функции.

PHP 5.2 не поддерживает Closures. Следовательно, вы не можете использовать ключевое слово use .

Если вам нужно, чтобы ваш код был совместимым с 5.2, вам было бы лучше просто создать именованную функцию / метод и передать необходимые параметры, а использовать create_function поскольку последний может вызвать утечку памяти (каждая функция создается каждый раз, а gc не поймать их всех).

Вы можете использовать global :

 create_function('$e','global $nr; return $e % $nr == 0;') 

Однако вам действительно нужно обновлять PHP, не беспокоясь о понижении: p

Вы можете использовать serialize / unserialize, как в:

 create_function('$e','return $e % unserialize(\''.serialize($nr).'\') == 0;')