- 确认开发环境
在 Linux 下开发 C 扩展需要先确认开发环境是否已经安装,主要包括以下几个部分:
- C 语言编译器
- PHP 源代码
- PHP 开发文件
- 调试工具
如果还没有安装对应的环境,可以通过 Linux 发行版的包管理器进行安装,比如使用 apt-get 命令安装 gcc,使用 yum 命令安装 php-devel。
- 编写扩展代码
编写扩展代码可以参考 PHP 官方提供的示例代码,在 PHP 的源代码安装目录下可以找到 /ext 目录,里面包含了各种扩展的示例代码。
假设我们要编写一个简单的扩展,用来计算两个数的平方和,以下是示例代码:
#include "php.h"
PHP_FUNCTION(square_sum)
{
double num1, num2;
double result;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "dd", &num1, &num2) == FAILURE) {
RETURN_NULL();
}
result = num1 * num1 + num2 * num2;
RETURN_DOUBLE(result);
}
zend_function_entry square_sum_functions[] = {
PHP_FE(square_sum, NULL)
{NULL, NULL, NULL}
};
zend_module_entry square_sum_module_entry = {
#if ZEND_MODULE_API_NO >= 20010901
STANDARD_MODULE_HEADER,
#endif
"square_sum",
square_sum_functions,
NULL,
NULL,
NULL,
NULL,
NULL,
#if ZEND_MODULE_API_NO >= 20010901
"0.1",
#endif
STANDARD_MODULE_PROPERTIES
};
#ifdef COMPILE_DL_SQUARE_SUM
ZEND_GET_MODULE(square_sum)
#endif
- 编译扩展
编写好扩展代码后,需要编译成共享库供 PHP 使用。可以用以下命令编译:
phpize
./configure
make
- 测试扩展
编译完成后,可以在命令行下测试扩展是否正确加载,可以通过以下命令测试:
php -d extension=modules/square_sum.so -r 'echo square_sum(3, 4);'
如果输出 25 则表示扩展加载成功。
示例1:自定义 php 语言结构
在 PHP 扩展中,可以自定义新的 PHP 语言结构,比如新的类、新的函数等。以下是一个简单的示例,演示如何在 PHP 中定义一个新的函数 my_add:
#include "php.h"
#include "ext/standard/info.h"
PHP_FUNCTION(my_add)
{
long num1, num2;
long result;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ll", &num1, &num2) == FAILURE) {
RETURN_NULL();
}
result = num1 + num2;
RETURN_LONG(result);
}
zend_function_entry my_functions[] = {
PHP_FE(my_add, NULL)
{NULL, NULL, NULL}
};
zend_module_entry my_module_entry = {
#if ZEND_MODULE_API_NO >= 20010901
STANDARD_MODULE_HEADER,
#endif
"my",
my_functions,
NULL,
NULL,
NULL,
NULL,
NULL,
#if ZEND_MODULE_API_NO >= 20010901
"0.1",
#endif
STANDARD_MODULE_PROPERTIES
};
#ifdef COMPILE_DL_MY
ZEND_GET_MODULE(my)
#endif
然后按照上述步骤进行编译并测试即可。
示例2:调用 PHP 函数
在 PHP 扩展中,也可以调用 PHP 中已经存在的函数,可以使用以下代码:
#include "php.h"
#include "ext/standard/info.h"
PHP_FUNCTION(my_strlen)
{
char *str;
int str_len;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &str_len) == FAILURE) {
RETURN_NULL();
}
RETURN_LONG(strlen(str));
}
PHP_FUNCTION(my_string_repeat)
{
char *str;
int str_len;
long repeat_times;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl", &str, &str_len, &repeat_times) == FAILURE) {
RETURN_NULL();
}
int orig_len = str_len;
for (int i = 1; i < repeat_times; i++) {
str = erealloc(str, str_len + orig_len);
memcpy(str + str_len, str, orig_len);
str_len += orig_len;
}
str[str_len] = '\0';
RETURN_STRINGL(str, str_len, 0);
}
zend_function_entry my_functions[] = {
PHP_FE(my_strlen, NULL)
PHP_FE(my_string_repeat, NULL)
{NULL, NULL, NULL}
};
zend_module_entry my_module_entry = {
#if ZEND_MODULE_API_NO >= 20010901
STANDARD_MODULE_HEADER,
#endif
"my",
my_functions,
NULL,
NULL,
NULL,
NULL,
NULL,
#if ZEND_MODULE_API_NO >= 20010901
"0.1",
#endif
STANDARD_MODULE_PROPERTIES
};
#ifdef COMPILE_DL_MY
ZEND_GET_MODULE(my)
#endif
再按照上述步骤进行编译并测试即可。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:linux下 C语言对 php 扩展 - Python技术站