c开发php拓展
原文:https://ollyxar.com/blog/php-c-extension
-------------------------------------------------------------
Speedup your PHP with C extension

Prelude
Nowadays we know a lot of PHP extensions like Phalcon or Swoole. But does it make sense to build them? That's the main question. To find out, we need to build at least one. So, let's do it!
Stage 1: prepare environment
To achieve the maximum performance we'll use only standard API for building our extension. That's mean that we need to learn some basics not only about C language but also about PHP API extensions.
The one (and probably only one) guide is www.phpinternalsbook.com. Unfortunately, lots of articles about PHP7 API are missing. But if you're brave enough and got some experience with C, this will not stop you on your way to build PHP7 extension.
The target for our extension will be Linux. Since I'm a web engineer, I work on Linux most of the time. But when I'm at home I prefer to use more convenient for me Windows. You might know, that if you want to build some programs for a certain platform, you need to build it on this exact platform. That's why we'll use Docker. This will allow us to work with our project on any platform you prefer.
In this example, we'll eventually build complete analog of Lumen-like routes
Clone ready to develop repository. Let's see how it's done.
Dockerfile
FROM alpine:latest
RUN apk --update --no-cache add autoconf g++ make git bison re2c \
libxml2-dev sqlite-dev pcre-dev && \
git clone https://github.com/php/php-src.git ./php-src && \
cd ./php-src && git checkout tags/php-7.3.6 && \
./buildconf --force && ./configure --prefix=/usr/local/php7 && \
make -j4 && make install
WORKDIR /src
These instructions will add all necessary dependencies for building our extension, then clone source repository of PHP, then choose PHP version 7.3.6, and finally build it with -j4
= four parallel processes just to not waste the time.
Then open cmd or powershell in the current directory and build image:
docker build -t php_ext:latest .
Stage 2: initial setup
Every time you need to build / compile your project you need to enter container using:
docker run --rm --name php_ext -v d:/projects/php_extensions/router/src:/src -it php_ext sh
.
Please make note that you have to change the directory according to your system.
This command used only once to create all necessary files for the project:
/usr/local/php7/bin/phpize && ./configure --with-php-config=/usr/local/php7/bin/php-config
This command will build your extension, clean up binaries and execute tests
make && make clean && make test && make install
Stage 3: Extension
Now let's take a closer look at the code.
First of all, since we're using regular expressions, we'll add a check for external dependency in config.m4
via AC_CHECK_HEADER
PHP_ARG_ENABLE(httprouter, for HTTPRouter support,
[ --enable-httprouter Include HTTPRouter support])
if test "$PHP_HTTPROUTER" != "no"; then
PHP_NEW_EXTENSION(httprouter, httprouter.c, $ext_shared)
CFLAGS="$CFLAGS -Wall -g"
AC_CHECK_HEADER(pcre.h, , [AC_MSG_ERROR([Couldn't find pcre.h, try installing the libpcre development/headers package])])
fi
Our extension has its own class and methods that should return self-instance. That's why in header-file we have to add a very useful template:
define RETURN_THIS() RETURN_ZVAL(getThis(), 1, 0)
Be careful with arguments in methods! Make sure that you're not assigning them to global variables. PHP engine will reduce usage and probably will reuse them next time. So once you've received parameter, copy its value to another variable. Or if you need to work with it later - better to use heap. But do not forget to free memory then! Otherwise, you'll have a memory leak.
Stage 4: comparison & conclusion
We've used scripts that run both approaches with 999 instances of Class 100 times.
Tests were made on Aser Aspire E15 (AMD A10) within docker container
Regular PHP Class | PHP Extension (C implementation) | |
---|---|---|
Time in seconds | 1.787871599197389 | 1.473563671112060 |
Overall | 1.21 times slower | 1.21 times faster |
The answer to the main question will be: you can increase the performance up to 21%. But you will probably spend much more time to implement the same functionality.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
2018-07-09 builder pattern
2018-07-09 【转】如何成为学霸
2017-07-09 golang中select case 的用途到底是啥