如何在同一个文件中编写多个版本的PHP而不会出错?

orb*_*ory 12 php anonymous-function preg-replace-callback

我试图使用version_compare在一个文件中支持一些PHP代码的两个版本,但我仍然收到错误.

码:

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);
}
Run Code Online (Sandbox Code Playgroud)

但我得到:

PHP Parse错误:语法错误,意外T_FUNCTION

preg_replace_callback()调用上,可能是因为匿名函数.

jer*_*ity 17

一种选择是将代码放在单独的文件中,如下所示:

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

然后在里面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);
Run Code Online (Sandbox Code Playgroud)

...并在里面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);
Run Code Online (Sandbox Code Playgroud)

  • @orbitory:PHP没有编译,它被解释=) (2认同)
  • @ Mints97:从技术上讲,就像今天的大多数脚本语言一样,PHP首先被解析并编译成内部表示,然后进行解释.这种区别在这里实际上是相关的,因为它意味着即使在永远不会被执行的代码中,解析器也会跳过语法错误. (2认同)

chi*_*NUT 16

无法使用版本检查来决定使用将导致先前版本中的解析错误的语言功能.无论分支如何,解析器都会查看整个文件.

如果该版本的lint检查失败,则无论分支如何都不起作用:

> php -l file.php
> PHP Parse error: syntax error, unexpected T_FUNCTION
Run Code Online (Sandbox Code Playgroud)

  • @orbitory这个答案从正确的断言开始,这是不可能的.PHP中没有预处理,因此无法从编译器中"隐藏"代码. (4认同)
  • @kmlnvm不会改变这个答案,这仍然是正确的 - OP通过条件询问如何使用新语法*当*可用时. (2认同)

use*_*740 6

解析PHP文件任何代码运行之前发生.该if-approach永远也不会相同的代码单元的工作-即.PHP文件.(不,我不会建议"eval".)

但是,如果存在不同的包含文件(每个版本一个),那么if可以选择要包含的文件 - 但是每个文件在解析它的PHP版本/上下文中仍然必须在语法上有效.

如果使用依赖注入或其某些变体,这实际上是一种"理智"的方法- 如果维护不同的组件实现非常重要.这是因为IoC容器/设置将确定要包含哪些文件/实现,并且服务使用者将不知道该更改.


ub3*_*t4r 5

我知道这个答案为什么你得到语法错误,但另一个选择是使用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);
Run Code Online (Sandbox Code Playgroud)

还应该注意的是,PHP不像其他编程语言(如C/C++)那样支持条件编译.然而,正如其他人所说,你可以得到它周围是利用require(),include()eval().