使用Zephir语言编写PHP扩展

写了7年PHP,说实话一直在用扩展,但是从来没写过。7年的功力让我的C语言水平远远不如大学的巅峰时期。那该怎么办呢?能不能用PHP语言去写PHP扩展呢?于是Phalcon Team给我们带来了zephir语言,一个可以写php扩展却又无比接近php的语言。
于是踩坑之路就此开启。

Centos7安装zephir

首先我们肯定得去找官网文档,对吧。然后。。。。。。写的稀烂,估计就是把英文版浏览器翻译一下成中文。摘取重要信息看吧。
先做个核心地址备忘吧:

Zephir Parser 扩展

zephir.phar

zephir

1.使用docker安装php7.4
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
docker pull php:7.4-fpm
docker run --name php74 -v /root/lnmp/www/:/var/www/html/ -d php:7.4-fpm

docker exec -it php74 bash

//更新软件源
apt update
//安装各种库
apt install -y libwebp-dev libjpeg-dev libpng-dev libzip-dev zlib1g-dev libfreetype6-dev

apt-get install libgmp-dev
apt-get install git

//编译安装
docker-php-ext-install gmp
docker-php-ext-install mysqli
docker-php-ext-install pdo_mysql
docker-php-ext-install zip
//查看是否成功安装gmp扩展
php -m | grep gmp
2.使用docker安装Zephir Parser 扩展

你也手动可以下载这个扩展包,拷贝到容器里面,地址放上面了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 进入php7.4容器
docker exec -it php74 bash;

# 下载
git clone git://github.com/phalcon/php-zephir-parser.git

# 拷贝到扩展目录
mv php-zephir-parser/ /usr/src/php/ext/

# 安装
docker-php-ext-install php-zephir-parser

# 检查一下
php -m
3.安装Zephir.phar 包

这个后面用来编译自己写的扩展,根据自己当前的PHP版本进行选择,我这里环境用的是PHP7.4版本。

1
2
3
4
5
6
7
8
9
10
11
# 下载
curl https://github.com/zephir-lang/zephir/releases/download/0.13.5/zephir.phar

# 设置为全局可用
mv zephir.phar /usr/local/bin/zephir

# 给个权限
chmod -R 777 /usr/local/bin/zephir

# 查看
zephir help
zephir源码

鉴于github那感人速度,先下载压缩包手动上传服务器吧。这里安装完后,也可以生成个zephir.phar包,全局执行。或者就以这个为开发环境,建立项目亦可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 下载zephir,拷贝到php容器,当扩展安装
docker cp zephir-development.zip php74:/var/www/html

# 解压
unzip zephir-development.zip

# 下载 PHP composer安装工具
curl -sS https://getcomposer.org/installer | php

# 设置为全局可用
mv composer.phar /usr/local/bin/composer

# 切换国内源
composer config -g repo.packagist composer https://packagist.phpcomposer.com

# 到zephir项目根目录安装
composer install -vvv

解决安装过程中的异常情况,当做备忘

  • composer必须2.x以上版本,如果还是1.8的请升级:

    composer self-update

  • 如果想回滚到之前版本:

    composer self-update --rollback

启动一个nginx服务,查看php信息

在www目录里面新增index.php文件,打印php信息。

1
docker run --name nginx-zephir -p 8084:80 -v /root/zephir/nginx/www:/usr/share/nginx/html -v /root/zephir/nginx/conf.d:/etc/nginx/conf.d -v /root/zephir/nginx/logs:/var/log/nginx --link php74:php -d nginx:1.9.5

手撸自己第一个PHP扩展

1.生成骨架

我们要做的第一件事就是生成扩展骨架。 这将为我们的扩展提供我们开始工作所需的基本结构。 在我们的示例中, 我们将创建一个名为 utils 的扩展
zephir init utils

目录 ext/ (内部实用程序) 包含编译器将用于生成扩展的代码。 创建的另一个目录是utils-此目录与我们的扩展具有相同的名称。 我们将把 Zephir 代码放在那里。

utils

ext

utils

config.json

目录列表还将向我们显示一个名为 config.json 的文件。 此文件包含配置设置, 我们可以使用这些设置来更改 Zephir 和/或扩展本身的行为。

2.写个hello的扩展

Zephir 旨在生成面向对象的扩展。 要开始开发功能, 我们需要将我们的第一个类添加到扩展中。

1
2
3
4
5
6
7
8
9
10
11
namespace Utils;

class Greeting
{


public static function say()
{

echo "hello world!";
}

}
  • 此类的代码必须放在 utils/utils/greeting.zep

接下来告诉 Zephir, 我们的项目必须编译并生成扩展。

1
zephir build
  • 切记在项目根目录下执行

最初,也只是第一次,执行了许多内部命令,生成必要的代码和配置,以便将该类导出到PHP扩展。 如果一切顺利, 您将在输出的末尾看到以下消息:

1
2
3
4
5

Extension installed.
Add "extension=utils.so" to your php.ini

! [NOTE] Don't forget to restart your web server

utils.so文件在ext/modules目录里面,拷贝到你的php扩展所在目录,在php.ini上添加这个扩展配置项。常规操作,这里不赘述了。