From 34c6566587c4e8dfac08339615aa67d0a2a2edc6 Mon Sep 17 00:00:00 2001 From: xtgxiso <124960772@qq.com> Date: Thu, 13 Oct 2016 16:23:11 +0800 Subject: [PATCH] Update 19.3.md --- 19.3.md | 70 +++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 46 insertions(+), 24 deletions(-) diff --git a/19.3.md b/19.3.md index db6f847..d577575 100644 --- a/19.3.md +++ b/19.3.md @@ -1,24 +1,46 @@ -# 通过嵌入包装重新创建cli - -现在php已经可以在你的应用中访问了, 是时候让它做⼀些事情了. 本章剩下的核心就是围绕着在这个测试应用框架中重新创建cli sapi展开的. - -很简单, cli二进制程序最基础的功能就是在命令行指定⼀个脚本的名字, 由php对其解 释执行. 用下面的代码替换你的embed1.c的内容就在你的应用中实现了cli. - -````c -#include #include int main(int argc, char *argv[]) { zend_file_handle script; /* 基本的参数检查 */ if ( argc <= 1 ) { fprintf(stderr, "Usage: %s \n", argv[0]); return -1; } /* 设置⼀一个文件处理结构 */ script.type script.filename script.opened_path script.free_filename if ( !(script.handle.fp = fopen(script.filename, "rb")) ) { fprintf(stderr, "Unable to open: %s\n", argv[1]); return -1; } /* 在将命令行参数注册给php时(php中的$argv/$argc), 忽略第一个命令行参数, 因为它对php脚本无意义 */ argc --; argv ++; PHP_EMBED_START_BLOCK(argc, argv) php_execute_script(&script TSRMLS_CC); PHP_EMBED_END_BLOCK() return 0; } 译注: 原著中的代码在译者的环境不能直接运行, 上面的代码是经过修改的. -```` - -当然, 你需要⼀个文件测试它, 创建⼀个小的php脚本, 命名为test.php, 在命令行使用你的embed程序执行它: - -````c -$ ./embed1 test.php -```` - -如果你给命令行传递了其他参数, 你可以在你的php脚本中使用$_SERVER['argc']/ $_SERVER['argv']看到它们. - -你可能注意到了, 在PHP_EMBED_START_BLOCK()和PHP_EMBED_END_BLOCK()之间 的代码是缩进的. 这个细节是因为这两个宏实际上构成了⼀个C语言的代码块作用域. 也就是说 PHP_EMBED_START_BLOCK()包含⼀个打开的花括号"{", 在PHP_EMBED_END_BLOCK()中 则有与之对应的关闭花括号"}". 这样做非常重要的一个问题是它们不能被放入到独立的启动/终止函数中. 下一章你将看到这个问题的解决方案. - -## links - * [目录]() - * 19.2 [构建并编译一个宿主应用](<19.2.md>) - * 19.4 [老技术新用](<19.4.md>) +# 通过嵌入包装重新创建cli + +现在php已经可以在你的应用中访问了, 是时候让它做⼀些事情了. 本章剩下的核心就是围绕着在这个测试应用框架中重新创建cli sapi展开的. + +很简单, cli二进制程序最基础的功能就是在命令行指定⼀个脚本的名字, 由php对其解 释执行. 用下面的代码替换你的embed1.c的内容就在你的应用中实现了cli. + +````c +#include +#include +int main(int argc, char *argv[]) { + zend_file_handle script; +/* 基本的参数检查 */ if ( argc <= 1 ) { + fprintf(stderr, "Usage: %s \n", argv[0]); +return -1; } +/* 设置⼀一个文件处理结构 */ +script.type = ZEND_HANDLE_FP; +script.filename = argv[1]; +script.opened_path = NULL; +script.free_filename = 0; +if ( !(script.handle.fp = fopen(script.filename, "rb")) ) { + fprintf(stderr, "Unable to open: %s\n", argv[1]); +return -1; } +/* 在将命令行参数注册给php时(php中的$argv/$argc), 忽略第一个命令行参数, 因为它对php脚本无意义 */ + argc --; + argv ++; + PHP_EMBED_START_BLOCK(argc, argv) + php_execute_script(&script TSRMLS_CC); + PHP_EMBED_END_BLOCK() +return 0; } +译注: 原著中的代码在译者的环境不能直接运行, 上面的代码是经过修改的. +```` + +当然, 你需要⼀个文件测试它, 创建⼀个小的php脚本, 命名为test.php, 在命令行使用你的embed程序执行它: + +````c +$ ./embed1 test.php +```` + +如果你给命令行传递了其他参数, 你可以在你的php脚本中使用$_SERVER['argc']/ $_SERVER['argv']看到它们. + +你可能注意到了, 在PHP_EMBED_START_BLOCK()和PHP_EMBED_END_BLOCK()之间 的代码是缩进的. 这个细节是因为这两个宏实际上构成了⼀个C语言的代码块作用域. 也就是说 PHP_EMBED_START_BLOCK()包含⼀个打开的花括号"{", 在PHP_EMBED_END_BLOCK()中 则有与之对应的关闭花括号"}". 这样做非常重要的一个问题是它们不能被放入到独立的启动/终止函数中. 下一章你将看到这个问题的解决方案. + +## links + * [目录]() + * 19.2 [构建并编译一个宿主应用](<19.2.md>) + * 19.4 [老技术新用](<19.4.md>)