ThinkChat🤖让你学习和工作更高效,注册即送10W Token,即刻开启你的AI之旅 广告
# 通过嵌入包装重新创建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 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 * [目录](<preface.md>) * 19.2 [构建并编译一个宿主应用](<19.2.md>) * 19.4 [老技术新用](<19.4.md>)