phper如何用Rust开发PHP扩展Liunx版[详细教程]

一、前言

众所周知,作为一名phper,对php有些功能的缺失有时会感到尴尬,比如:调用ffmpeg视频处理工具。没有专门的扩展来操作的,什么?利用php system函数调用?对于开源的php脚本,这太不安全了!这个时候作为深资的phper会考虑开发php扩展,在扩展中实现对ffmpeg的操作。

为什么要使用php扩展?

优点:

  • php扩展是C开发的,那速度没得说。

  • 耦合性高,它的出现就是用来增强php的。

  • 安全性高,毕竟扩展是编译后的程序,代码不开源。

缺点:

  • 需针对php版本及系统环境进行开发,那么就比较麻烦了。也就是说7.4版本的php,liunx环境下开发的扩展,只支持该php版本及系统。

  • 需要会C、C++,当然本文是以rust进行开发,对C的数据类型进行了解,对rust FFI的操作及数据类型转换需精通。

  • 调试相对麻烦。

为什么要用rust开发php扩展?

原因很简单,这还要说起rust的语言特性

因“所有权”的特性使你的程序更安全,不会像C那样出现各种“玄学BUG”。拥有C一样的性能,我还是很看好它的发展。

rust开发php扩展流程:

当然,rust目前是没有专门开发php扩展的骨架。所以我的逻辑也很简单,利用rust开发静态库暴露给C【涉及FFI的了解】。我们在php官方骨架中直接引入rust静态库调用其方法即可。

二、开发环境与流程

开发环境

宝塔【CentOS 7.6】、GCC【涉及php扩展骨架的编译,我这里系统内置就有,如果编译扩展报相关错了自行安装】、对应php版本源码、web环境【宝塔中安装对应php版本、nginx、mysql等等】

开发整体流程:

1、准备宝塔,安装这里就不说了

图片

这里我们以开发php7.4扩展为例。

图片

2、下载php7.4 liunx版源码

php官网:www.php.net/

图片

图片

注意!该源码版本必须与你环境php版本完全一致!!!

图片

3、上传php源码到宝塔

图片

/usr/phper

在usr下创建一个phper文件夹,然后将源码压缩包上传到此处。

图片

解压该压缩包

图片

4、创建一个我们自己的扩展

图片

/usr/phper/php-7.4.30/ext目录下有这么一个php文件,它可以创建扩展!

图片

注意设置命令行版本,因为接下来利用php命令必须是版本一致的!

图片

在刚刚的目录下,点击终端,输入创建扩展命令。

php ext_skel.php --ext 扩展名称

图片

图片

这里就多出了一个新的扩展源码文件。

图片

图片

在该目录下点击终端,输入:

phpize

图片

图片

接着输入:

./configure --with-php-config=/www/server/php/74/bin/php-config

注意这个参数php路径,如果是别的版本,请自行在宝塔里安装找到对应版本路径,它们都是放一起的。

图片

回车开始进行检查了

图片

最后输入:

make

进行编译。

图片

图片

这个目录下便是编译出来的so扩展最终文件了!

图片

让我们看下默认生成的扩展有哪些功能

图片

查看主文件【需了解php扩展骨架,这里以它默认给的为例】

图片

也就是说,刚刚编译出来的扩展,是有这两个函数的,咱们测试一下玩玩。

注意!每次修改主文件,都需要重新按上述命令跑一遍,否则不生效,很奇怪!

phpize

5、使用扩展

图片

复制刚刚生成的扩展文件到我们php环境的扩展里

图片

图片

配置php.ini加载hello.so扩展

图片

extension = hello.so

保存后记得重新启动下php,否则不生效的!

图片

图片

在文件管理中点击终端,输入:

php -m

可以看到我们的扩展在列表中了。

创建一个站点,测试下扩展中两个函数。

图片

看好,php版本是7.4

图片

图片

访问站点,发现没有问题。

当然也可以通过命令行运行php脚本查看结果【前提是网站那里php命令行版本设置的7.4】

php index.php

OK!从创建到生成到使用扩展的流程结束,接下来才进入正题,开始用rust开发扩展。

6、rust与php扩展的整合开发

开发工具:CLion

需要rust环境与CLion中rust插件的安装与配置,这个自行去百度,比我想象中的全!

图片

创建一个hello命名的库项目

图片

我们写两个导出函数,分别是加法功能和base64字符串解析功能。

图片

lib.rs

#![crate_type = "staticlib"]

图片

Cargo.toml

[package]

注意在编译过程中涉及系统类型,不然在引入该静态库编译扩展可能报错,提示不支持。

编译64位静态库

rustup target add x86_64-unknown-linux-musl

编译32位静态库

rustup target add i686-unknown-linux-musl

这里我们是64位系统。

图片

会生成一个.a文件,该文件便是liunx支持的静态库文件。

生成支持C语言的胶水头文件【用于C调用该库需要写的函数声明,很方便】

创建cbindgen.toml文件

内容:

language = "C"

图片

安装cbindgen,创建头文件。

cargo install --force cbindgen

图片

图片

自动生成了C语言的函数声明hello.h文件,用于调用。

图片

回到之前我们创建的hello扩展

创建lib文件夹

图片

将刚刚编译出来的静态库.a文件上传到lib目录下

图片

将刚刚创建的.h头文件上传到扩展目录下

图片

配置.m4预编译文件【关键】

图片

设置引入lib文件夹中的静态库文件

图片

  PHP_ADD_LIBRARY_WITH_PATH(hello, /usr/phper/php-7.4.30/ext/hello/lib, HELLO_SHARED_LIBADD)

图片

保存.m4

图片

编写主文件

图片

/* hello extension for PHP */

删除之前生成的扩展文件

图片

重新生成扩展

图片

phpize

图片

大小都变了,说明我们的静态库在里面了哈哈。

按上述使用扩展流程替换扩展

图片

注意!替换扩展文件后要重启PHP哦,不然不生效!

7、测试rust开发的php扩展

图片

网页测试和命令行测试

图片

也可以通过php扩展骨架直接进行测试

图片

图片

图片

编写要执行测试的扩展函数

--TEST--

图片

扩展目录下直接输入:

make test

图片

执行后 tests目录下输出了一个.out文件

图片

是不是这样更方便了呢?

以上就是整体的开发流程,需要自己操作的话还是多少要了解C语言、php扩展骨架、rust精通。如有错误请多包涵!
原文地址:mp.weixin.qq.com/s/ixi1Dge6MenqUTt...

本作品采用《CC 协议》,转载必须注明作者和本文链接
最美的不是下雨天,而是和你一起躲过的屋檐!
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 4

学习了, :+1:

1年前 评论

步骤真细

10个月前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!