анонимная функция — Как я могу без ошибок кодировать несколько версий PHP в одном файле?

Я пытаюсь поддержать две версии некоторых PHP код в одном файле с использованием version_compare, но я все еще получаю ошибку.

Код:

if (version_compare(PHP_VERSION, '5.3.0') >= 0) {
$alias = preg_replace_callback('/&#x([0-9a-f]{1,7});/i', function($matches) { return chr(hexdec($matches[1])); }, $alias);
$alias = preg_replace_callback('/&#([0-9]{1,7});/', function($matches) { return chr($matches[1]); }, $alias);
} else {
$alias = preg_replace('/&#x([0-9a-f]{1,7});/ei', 'chr(hexdec("\\1"))', $alias);
$alias = preg_replace('/&#([0-9]{1,7});/e', 'chr("\\1")', $alias);
}

Но я получаю:

Ошибка синтаксического анализа PHP: синтаксическая ошибка, неожиданный T_FUNCTION

На preg_replace_callback() звонки, вероятно, из-за анонимных функций.

11

Решение

Невозможно использовать проверку версий, чтобы принять решение об использовании языковой функции, которая вызовет ошибку разбора в предыдущей версии. Парсер просматривает весь файл независимо от ветвления.

Если проверка lint не удалась для этой версии, она не будет работать, независимо от ветвления:

> php -l file.php
> PHP Parse error: syntax error, unexpected T_FUNCTION
16

Другие решения

Один из вариантов — поместить код в отдельные файлы, например так:

if (version_compare(PHP_VERSION, '5.3.0') >= 0) {
include('file-5.3.0.php');
} else {
include('file-5.x.php');
}

Тогда внутри file-5.3.0.php, добавьте соответствующий код:

$alias = preg_replace_callback('/&#x([0-9a-f]{1,7});/i', function($matches) { return chr(hexdec($matches[1])); }, $alias);
$alias = preg_replace_callback('/&#([0-9]{1,7});/', function($matches) { return chr($matches[1]); }, $alias);

… и внутри file-5.x.php добавьте оставшийся код:

$alias = preg_replace('/&#x([0-9a-f]{1,7});/ei', 'chr(hexdec("\\1"))', $alias);
$alias = preg_replace('/&#([0-9]{1,7});/e', 'chr("\\1")', $alias);
17

Разбор PHP файлов происходит до любой код запускается. if-подход никогда не будет работать через одну и ту же кодовую единицу — т.е. PHP-файл (И нет, я не буду один, чтобы предложить «Eval».)

Однако, если бы был другой включенный файл (по одному для каждой версии), затем if мог выбрать, какой файл включить — но каждый из файлов должен все еще быть синтаксически действительным в версии / контексте PHP, в котором он анализируется.

Это на самом деле «здравый» подход к использованию при использовании Dependency Injection или какой-либо их вариант — если действительно важно поддерживать различные реализации компонентов. Это связано с тем, что контейнер / настройка IoC будет определять, какой файл (-ы) / реализацию (-и) следует включить, а потребители услуг не будут зависеть от изменений.

6

Я знаю этот ответ, почему вы получаете синтаксическую ошибку, но другой вариант заключается в использовании create_function() который совместим с PHP v4 и v5 …

$alias = preg_replace(
'/&#x([0-9a-f]{1,7});/i',
create_function(
'$matches',
'return chr(hexdec($matches[1]));'
),
$alias);
$alias = preg_replace(
'/&#([0-9]{1,7});/',
create_function(
'$matches',
'return chr($matches[1]);'
),
$alias);

Следует также отметить, что PHP не поддерживает условную компиляцию, как другие языки программирования (такие как C / C ++). Однако, как утверждают другие, вы можете обойти это, используя require(), include() или же eval(),

5

Просто сделайте это так, и это также должно работать для версий php до 5.3, которые не поддерживают анонимные функции:

function one($matches) {
return chr(hexdec($matches[1]));
}

function two($matches) {
return chr($matches[1]);
}

$alias = preg_replace_callback('/&#x([0-9a-f]{1,7});/i', "one", $alias);
//^^^^ See here I
//just passed the function name
//as string
$alias = preg_replace_callback('/&#([0-9]{1,7});/', "two", $alias);
2

Вы могли бы использовать eval а также запись heredoc, но, как Илмари Каронен Как указывалось выше, heredocs действуют как строки в двойных кавычках, а переменные будут интерполированы. Это требует экранирования всех знаков $, что может быть грязно.

Кроме того, вы можете использовать eval а также нотация нотаций, который, к сожалению, доступен только в PHP 5.3.0 и выше. eval обычно запрещен, но в этой ситуации строка не указана пользователем, и поэтому нет угрозы безопасности.

if (version_compare(PHP_VERSION, '5.3.0') >= 0) {
eval(<<<'CODE'
$alias = preg_replace_callback('/&#x([0-9a-f]{1,7});/i', function($matches) { return chr(hexdec($matches[1])); }, $alias);
$alias = preg_replace_callback('/&#([0-9]{1,7});/', function($matches) { return chr($matches[1]); }, $alias);
CODE
);
} else {
eval(<<<'CODE'
$alias = preg_replace('/&#x([0-9a-f]{1,7});/ei', 'chr(hexdec("\\1"))', $alias);
$alias = preg_replace('/&#([0-9]{1,7});/e', 'chr("\\1")', $alias);
CODE
);
}

Насколько я знаю, это ближе всего к намерению ОП. Кроме того, если есть хорошее время и место для использования eval, эта ситуация как раз то время и место.

2
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector