Я пытаюсь поддержать две версии некоторых 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()
звонки, вероятно, из-за анонимных функций.
Невозможно использовать проверку версий, чтобы принять решение об использовании языковой функции, которая вызовет ошибку разбора в предыдущей версии. Парсер просматривает весь файл независимо от ветвления.
Если проверка lint не удалась для этой версии, она не будет работать, независимо от ветвления:
> php -l file.php
> PHP Parse error: syntax error, unexpected T_FUNCTION
Один из вариантов — поместить код в отдельные файлы, например так:
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);
Разбор PHP файлов происходит до любой код запускается. if
-подход никогда не будет работать через одну и ту же кодовую единицу — т.е. PHP-файл (И нет, я не буду один, чтобы предложить «Eval».)
Однако, если бы был другой включенный файл (по одному для каждой версии), затем if
мог выбрать, какой файл включить — но каждый из файлов должен все еще быть синтаксически действительным в версии / контексте PHP, в котором он анализируется.
Это на самом деле «здравый» подход к использованию при использовании Dependency Injection или какой-либо их вариант — если действительно важно поддерживать различные реализации компонентов. Это связано с тем, что контейнер / настройка IoC будет определять, какой файл (-ы) / реализацию (-и) следует включить, а потребители услуг не будут зависеть от изменений.
Я знаю этот ответ, почему вы получаете синтаксическую ошибку, но другой вариант заключается в использовании 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()
,
Просто сделайте это так, и это также должно работать для версий 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);
Вы могли бы использовать 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
, эта ситуация как раз то время и место.