在PHP 7.4中是只读的



我使用PHP 8.0readonly关键字编写了一个PHP库,然后我意识到它将很好地支持早期版本的PHP,如7.4。

我可以很容易地从我的代码中删除readonly关键字,但我不想这样做——他们放在那里是有原因的!

有C背景,我马上想到了宏,但PHP似乎没有。我已经在谷歌上搜索了这个答案,以便在PHP中添加类似宏的行为,但它看起来像是多余的。这只是一个文件,而我的库目前有26个文件。

是否有一个简单的方法使PHP 7.4只是忽略readonly关键字,使我的代码跨版本?这段C代码有什么影响吗?

#if PHP_VERSION < 8
#define readonly /**/
#enif

也许一些composer构建选项,可以在打包之前预处理文件?

开箱即用,PHP不包含您所希望的类型的条件编译。

一种选择是使用自定义的自动加载器或Composer钩子动态地预处理源文件。我们的想法是让正常的代码运行到要include文件的地方,然后获取其内容并对其进行操作。

请注意,这并不需要是一个功能齐全的宏系统,您可以只用一些清晰的标记来包围代码,如/* IF PHP 8 */ readonly /* END IF */,并将它们与一个简单的正则表达式模式匹配:
$php_code = file_get_contents($php_file_being_loaded);
if ( PHP_VERSION_ID < 80000 ) {
$php_code = preg_replace('#/* IF PHP 8 */.*?/* END IF */#s', '', $php_code);
}
eval($php_code);

或者,您可以"离线"运行预处理,以自动生成库的并行版本:一个用于PHP 8.0及以上版本,另一个用于PHP 7.4。同样,这可以像上面一样简单,或者您可以使用像Rector这样的工具,它可以根据设置的规则(包括"降级")解析和重写普通的PHP代码(没有额外的标记)。

PHP没有被编译,因此没有编译器宏。
根据向后不兼容的变化,它是一个新的关键字:

readonly现在是一个关键字。但是,它仍然可以用作函数名。

所以你有两个选择:a)不重新赋值或者b)保持两个版本。

大多数框架只是因为这个原因而避免使用现代功能(WordPress, Symfony, Laravel),但如果你坚持,你最好的选择可能是Composer,你可以有一个v1.x。X with composer.json

{
"require": {
"php": ">=7.4"
},
}

和一个v2.x。X with composer.json

{
"require": {
"php": ">=8.0"
},
}

然后当人们执行composer require lib时,composer会自动扫描并安装与本地php版本和composer兼容的库的最新版本。json-constraints (-:

缺点是,只要您打算支持PHP 7.4,您就必须同时维护库的v1和v2 .

另一种选择是使用lib.php

这样的加载器
if(PHP_MAJOR_VERSION >= 8){
require("lib_modern.php");
} else{
require("lib_legacy.php");
}

的缺点是必须同时维护lib_modern和lib_legacy

相关内容

  • 没有找到相关文章

最新更新