Skip to content

Update 19.3.md #146

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 46 additions & 24 deletions 19.3.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,46 @@
# 通过嵌入包装重新创建cli

现在php已经可以在你的应用中访问了, 是时候让它做⼀些事情了. 本章剩下的核心就是围绕着在这个测试应用框架中重新创建cli sapi展开的.

很简单, cli二进制程序最基础的功能就是在命令行指定⼀个脚本的名字, 由php对其解 释执行. 用下面的代码替换你的embed1.c的内容就在你的应用中实现了cli.

````c
#include <stdio.h>#include <sapi/embed/php_embed.h>int main(int argc, char *argv[]) { zend_file_handle script;/* 基本的参数检查 */ if ( argc <= 1 ) { fprintf(stderr, "Usage: %s <filename.php> <arguments>\n", argv[0]);return -1; }/* 设置⼀一个文件处理结构 */script.typescript.filenamescript.opened_pathscript.free_filenameif ( !(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
* [目录](<preface.md>)
* 19.2 [构建并编译一个宿主应用](<19.2.md>)
* 19.4 [老技术新用](<19.4.md>)
# 通过嵌入包装重新创建cli

现在php已经可以在你的应用中访问了, 是时候让它做⼀些事情了. 本章剩下的核心就是围绕着在这个测试应用框架中重新创建cli sapi展开的.

很简单, cli二进制程序最基础的功能就是在命令行指定⼀个脚本的名字, 由php对其解 释执行. 用下面的代码替换你的embed1.c的内容就在你的应用中实现了cli.

````c
#include <stdio.h>
#include <sapi/embed/php_embed.h>
int main(int argc, char *argv[]) {
zend_file_handle script;
/* 基本的参数检查 */ if ( argc <= 1 ) {
fprintf(stderr, "Usage: %s <filename.php> <arguments>\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
* [目录](<preface.md>)
* 19.2 [构建并编译一个宿主应用](<19.2.md>)
* 19.4 [老技术新用](<19.4.md>)