Как я могу кодировать несколько версий 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()
, возможно, из-за анонимных функций.
Ответы
Ответ 1
Невозможно использовать проверку версий, чтобы решить использовать функцию языка, которая приведет к ошибке синтаксического анализа в предыдущей версии. Парсер просматривает весь файл, независимо от его ветвления.
Если проверка строки не выполняется для этой версии, она не будет работать, независимо от ветвления:
> php -l file.php
> PHP Parse error: syntax error, unexpected T_FUNCTION
Ответ 2
Один вариант - поместить код в отдельные файлы, например:
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);
Ответ 3
Анализ файлов PHP происходит до запуска любого кода. if
-подход никогда не будет работать через один и тот же блок кода - то есть. PHP файл. (И нет, я не буду предлагать "eval".)
Однако, если бы был другой файл с включенным (по одному для каждой версии), то if
мог выбрать, какой файл включать, но каждый из файлов должен быть синтаксически действительным в версии PHP/контексте, в котором он анализируется.
Это фактически "здравомыслящий" подход к использованию при использовании Injection Dependency или некоторых его вариаций - если действительно важно поддерживать различные реализации компонентов. Это связано с тем, что контейнер/настройка IoC определит, какие файлы (файлы)/реализации должны быть включены, а потребители услуг будут агностически изменены.
Ответ 4
Я знаю этот ответ, почему вы получаете синтаксическую ошибку, но еще один вариант - использовать 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/С++). Однако, как заявили другие, вы можете использовать его для использования 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);
Ответ 6
Вы можете использовать eval
и heredoc нотацию, но как Ilmari Karonen указал, heredocs действуют как строки с двойными кавычками, а переменные будут интерполированы. Для этого требуется, чтобы все знаки $были экранированы, что может быть беспорядочным.
В качестве альтернативы вы можете использовать eval
и nowdoc нотацию, которая, к сожалению, доступна только в 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
);
}
Насколько я знаю, это ближе всего к намерению OP. Кроме того, если есть хорошее время и место для использования eval
, эта ситуация точно такова, что время и место.