C++开发PHP扩展

发布时间 2023-04-04 16:35:25作者: Scott_pb

前端时间用C开发PHP扩展,用C实现字符串和简单的cache不友好,因而有了用C++开发的想法。

相关环境初始化配置准备

1.用php源码提供的脚手架生成扩展名

php ext/ext_skel.php --ext yaoling_encrypt_plus

2.修改生成的config.m4

PHP_REQUIRE_CXX()
PHP_SUBST(YAOLING_ENCRYPT_PLUS_SHARED_LIBADD)
PHP_ADD_LIBRARY(stdc++, 1, YAOLING_ENCRYPT_PLUS_SHARED_LIBADD)
PHP_NEW_EXTENSION(yaoling_encrypt_plus, yaoling_encrypt_plus.cpp, $ext_shared)

3.修改yaoling_encrypt_plus.c 为 yaoling_encrypt_plus.cpp 修改源码

/* yaoling_encrypt_plus extension for PHP */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

extern "C"
{
#include "php.h"
#include "ext/standard/info.h"
#include "php_yaoling_encrypt_plus.h"
#include "yaoling_encrypt_plus_arginfo.h"
}
#include <iostream>

/* For compatibility with older PHP versions */
#ifndef ZEND_PARSE_PARAMETERS_NONE
#define ZEND_PARSE_PARAMETERS_NONE()  \
	ZEND_PARSE_PARAMETERS_START(0, 0) \
	ZEND_PARSE_PARAMETERS_END()
#endif


/* {{{ PHP_RINIT_FUNCTION Request initialization */
PHP_RINIT_FUNCTION(yaoling_encrypt_plus)
{
#if defined(ZTS) && defined(COMPILE_DL_YAOLING_ENCRYPT_PLUS)
	ZEND_TSRMLS_CACHE_UPDATE();
#endif
	std::cout << "yaoling_encrypt_plus request before..." << std::endl;
	return SUCCESS;
}
/* }}} */

/* {{{ PHP_MINFO_FUNCTION */
PHP_MINFO_FUNCTION(yaoling_encrypt_plus)
{
	php_info_print_table_start();
	php_info_print_table_header(2, "yaoling_encrypt_plus support", "enabled");
	php_info_print_table_end();
}
/* }}} */

/* {{{ yaoling_encrypt_plus_module_entry */
zend_module_entry yaoling_encrypt_plus_module_entry = {
	STANDARD_MODULE_HEADER,
	"yaoling_encrypt_plus",			  /* Extension name */
	ext_functions,					  /* zend_function_entry */
	NULL,							  /* PHP_MINIT - Module initialization */
	NULL,							  /* PHP_MSHUTDOWN - Module shutdown */
	PHP_RINIT(yaoling_encrypt_plus),  /* PHP_RINIT - Request initialization */
	NULL,							  /* PHP_RSHUTDOWN - Request shutdown */
	PHP_MINFO(yaoling_encrypt_plus),  /* PHP_MINFO - Module info */
	PHP_YAOLING_ENCRYPT_PLUS_VERSION, /* Version */
	STANDARD_MODULE_PROPERTIES};
/* }}} */

#ifdef COMPILE_DL_YAOLING_ENCRYPT_PLUS
#ifdef ZTS
ZEND_TSRMLS_CACHE_DEFINE()
#endif
extern "C"
{
	ZEND_GET_MODULE(yaoling_encrypt_plus)
}
#endif

4.修改定义方法

<?php

  /** @generate-class-entries */

  function yaoling_encrypt_plus(): void {}

5.重新生成头文件

php /usr/local/src/php-src-php-8.1.11/build/gen_stub.php \
    ./yaoling_encrypt_plus.stub.php

6.执行编译

phpize
./confugure --with-php-config=/usr/local/php8.1.11/bin/php-config
make && make install

7.配置ini

extension=yaoling_encrypt_plus

8.验证

php -r "yaoling_encrypt_plus();"
看到以下输出即为成功
yaoling_encrypt_plus request before... #c++语法的输出
The extension php_hello is loaded and working!