在 C++ 中嵌入 PHP(php5embed)

本文介绍如何通过 PHP 的 embed SAPI 将 PHP 嵌入 C++ 程序,以便在 C++ 中直接执行 PHP 代码。

编译步骤

  1. 首先编译 PHP 的 embed 模式,得到 php5embed.lib,然后在 C++ 项目中引入该 lib。
  2. 打开 PHP 源码目录下的 sapi\embed\php5embed.dsp,用 VS2013 打开后直接编译即可。
  3. 如果提示找不到 config.w32.h,需要用 VS 的命令行工具运行 buildconf.bat 生成 configure.bat。运行时需要 bison.exe,下载后添加到目录即可。
  4. 将所需的 DLL 添加到项目目录,并在代码中加入以下依赖。

示例代码

以下是一个通过 php5embed 执行 PHP 脚本文件的 C++ 示例:


#define ZEND_WIN32
#define PHP_WIN32
#define ZTS 1
#define ZEND_DEBUG 0

#include <php.h>
#include <php_embed.h>

#pragma comment (lib,"php5embed")

int main(int argc, char** argv) {

	/*char *s = "echo \"Hello world!\\n\";";

	PHP_EMBED_START_BLOCK(argc, argv);

	zend_eval_string(s, 0, "  " TSRMLS_CC);

	PHP_EMBED_END_BLOCK();
	system("pause");
	return  0;*/


//	std::cout << buf;

	char *eval_string = "    <html><body><h1>我的第一张 PHP 页面</h1>  ";
	"<? php echo \"Hello World!\";?></body></html>  ";

	char *php_code = "echo \"Hello, phpteam!\n\";";
	zval ret_value;
	void ***tsrm_ls;
	int exit_status;

	php_embed_init(argc, argv PTSRMLS_CC);

	zend_stream str;
	memset((void*)(&str), 0, sizeof (zend_stream));

	zend_file_handle f;
	f.filename = "1.php";
	f.type = ZEND_HANDLE_FILENAME;
	f.opened_path = NULL;
	f.free_filename = 0;
	//f.handle.fp = stdin;
	f.handle.fd = 0;
	f.handle.stream = str;


	zend_first_try{
		php_execute_simple_script(&f , TSRMLS_CC);

	} zend_end_try();

	php_embed_shutdown(TSRMLS_C);



	system("pause");

	return 0;
}

 

输出说明

PHP 解析后产生的 HTML 会输出到 stdout。

zend_eval_string 内部将输出重定向到了 stdout;如需将输出内容提取到其他用途,可以通过挂载模块来实现。

也可以通过 SAPI 来进一步扩展 PHP 的功能。