是什么?
Zephir,一种开源的高级语言,旨在简化PHP扩展的创建和可维护性,重点关注类型和内存安全性。
PHP框架(扩展)Phalcon团队为了更方便的开发,同时维护了zephir项目,并在Phalcon的v2-v4版本中应用。可惜2020年中,zephir主要维护者Serghei离开后,Phalcon宣布v5版本将使用原生PHP开发。此后Zephir再没有大的更新,除2021年3月发布v0.13兼容PHP8,其它就是一些维护类的更新。
https://blog.phalcon.io/post/the-future-of-phalcon
当前最新release版本为 0.15,但文档版本仅更新到 0.12,参考:
https://docs.zephir-lang.com/0.12/en/welcome
小知识:
Zephir 这个名字是单词 z (end) e (ngine)/ph (p)/i (nte) r (mediate) 的收缩。官方建议读作zephyr,而他的创造者实际把它读作zaefire。
为什么?
使用zephir有几个好处:
-
性能提升: 将一些不常变化的类库编译为扩展,避免每次请求都重新加载执行,浪费CPU; 另外zephir会将代码转换为PHP标准的C代码扩展,编译器在编译扩展时会做一些优化;
-
开发简单: 相比直接使用C开发PHP扩展,以一种类似PHP语法的方式编写,大大提升开发效率;
-
代码保护: PHP是解释型语言,通常是直接暴露源代码; 通过扩展方式发布,可以隐藏原始代码。对于发行软件可以保护知识产权;对于自研系统,可以避免敏感信息泄露,提升安全性;
当然,使用zephir的一些注意:
-
应该仅将需要优化性能或者保护信息的部分代码改写,因为zephir的开发效率弱于比直接使用PHP;
-
使用zephir开发扩展,相比纯PHP系统,增加了项目开发,部署和维护成本;
-
因为扩展生命周期是进程级别,现在发布代码可能需要重启php-fpm;
-
zephir项目生态上最主要的使用者Phalcon已经弃用,目前仅处于维护状态,未来有搁浅风险;
总的说来,zephir适合的应用场景较窄,请谨慎选择!
怎么做?
版本选择
0.13及之后版本只支持PHP7.4和PHP8, 0.12支持PHP7.2 - PHP7.4,可以按需要选择。实际开发大同小异,本文以0.12为例,环境为 centos 7 + php7.3。
安装
安装zephir:
zephir提供了打包好的phar文件,直接下载使用即可:
wget https://github.com/zephir-lang/zephir/releases/download/0.12.21/zephir.phar
# 提供一个tx云cos地址:https://public-pkg-1252772859.cos.ap-guangzhou.myqcloud.com/hyperf-box/zephir-v0.12.21.phar
chmod 755 zephir.phar
ln -s /usr/local/bin/zephir zephir.phar
# 查看是否安装成功
zephir -v
zephir编译代码时需要使用zephir-parser扩展。安装:
# 安装编译环境(按需)
sudo yum install php-devel gcc make re2c autoconf automake
# 说明: zephir-parser最新版是 v1.4.1,但该版本与 zephir 0.12不兼容
wget https://github.com/zephir-lang/php-zephir-parser/archive/refs/tags/v1.3.8.tar.gz -O zephir-parser.tgz
# 同样提供一个tx云cos地址: https://public-pkg-1252772859.cos.ap-guangzhou.myqcloud.com/hyperf-box/php-zephir-parser-1.3.8.tar.gz
tar zxvf zephir-parser.tgz
cd php-zephir-parser-1.3.8/
# 注意根据实际地址修改 phpize 和 php-config 路径
/usr/local/bin/phpize
./configure --with-php-config=/usr/local/bin/php-config
make
sudo make install
# 在 php.ini 中启用扩展
[zephir parser]
extension=zephir_parser.so
# 测试(说明:此版本扩展名称是 Zephir Parser;v1.4.1 起扩展名称改为了 zephir_parser
/usr/local/bin/php -m | grep -i zephir
/usr/local/bin/php --ri "zephir parser"
安装中细节有疑问的,可以参考官方文档:
https://docs.zephir-lang.com/0.12/en/installation
https://github.com/zephir-lang/php-zephir-parser
开发
hello world:
# 创建环境
zephir init demo
cd demo
ls
# config.json demo ext
# 有2个目录: ext 是生成扩展的代码; demo(与项目同名)目录是编码的地方
# 还有一个 config.json 的文件。可以使用配置,更改 Zephir 和/或扩展本身的行为
# 创建类
cat > demo/Hello.zep
namespace Demo;
class Hello
{
public static function say(string name="world")
{
echo "hello ".name."!\n";
}
}
# 生成扩展代码
zephir generate
# vim ext/demo/hello.zep.c 可以查看生成的C代码
# 编译安装同标准php扩展,略
# 测试
php -r "Demo\Hello::say('zephir');"
语法学习:
zephir的语法不复杂,有一点像 php + js 结合体,详细见:
https://docs.zephir-lang.com/0.12/en/language
一些注意:
-
在 zephir 中,每个文件都必须包含且仅包含一个类。每个类都必须有一个命名空间,并且目录结构必须与所使用的类和命名空间的名称相匹配。
-
zephir可以使用PHP内置的各种函数; 甚至还可以使用运行时存在的用户自定义函数和超全局变量等。
-
函数参数即使指定了类型,也不会强校验,只是会尝试转化类型;如上面例子执行
php -r "Demo\Hello::say(123);"
依然可以正常出结果 。如果需要强制校验,需要在参数后面追加一个叹号(!)。
高级技巧:
编译配置:
https://docs.zephir-lang.com/0.12/en/config
PHP生命周期事件钩子:
https://docs.zephir-lang.com/0.12/en/lifecycle
扩展练习:
我们可以尝试一下zephir编写一个微型PHP框架扩展,仅包含:配置文件加载(Config类),日志文件记录(Logger类)和数据库查询(Db类)。
详见项目: https://gitee.com/dingusxp/zephir-hellophp
经验
使用zephir改造PHP代码还是很简单的。先写PHP代码,再照以下步骤转化:
-
字符串单引号替换为双引号;
-
变量去掉 $ 符号;
-
变量预定义,使用 var 或者具体类型(int/string/array等);
-
变量赋值语句前面加上 let;
-
for循环语句转换为loop,参考:
foreach ($data as $key => $value)
=>for (key, value in data)
,for ($i = 0; $i < 10; $i++)
=>loop (i in range(0, 9))
; -
异常捕捉语句修改,参考:
catch (Exception $e)
=>catch Exception, e
; -
一般以上步骤完成已经改的七七八八了; 接下来直接执行
zephir generate
尝试生成扩展(一般不会这么顺利),并按提示修改代码。
Phalcon的v4最后发行版还是使用zephir,可以学习其源码:
https://github.com/phalcon/cphalcon/tree/4.1.2-release/phalcon