php扩展中如何获取命令行参数,以及什么是SG

在思考zan框架如何解决热加载问题的时候,想着能不能每次也像fpm那样 rint,然后再调用php_execute_script执行,因为php_execute_script需要拿到php文件脚本的地址和参数,所以我遇到了如何在扩展内部获取命令行参数和脚本文件名,我们知道在php上次程序中可以直接调用$argv获取,那在扩展中如何拿到呢

我分析了sapi下的php_cli文件源码,发现参数是直接在 main(int argc, char *argv[])函数获取,然后在do_cli文件内复制给了SG 如下

[code lang=”c”]

static int do_cli(int argc, char **argv) /* {{{ */
{
//….中间代码省略

SG(request_info).argc=argc-php_optind+1;
arg_excp = argv+php_optind-1;
arg_free = argv[php_optind-1];
SG(request_info).path_translated = translated_path? translated_path: (char*)file_handle.filename;
argv[php_optind-1] = (char*)file_handle.filename;
SG(request_info).argv=argv+php_optind-1;

//….
}
[/code]

昨天看php-fpm源码的时候 他会调用init_request_info(fcgi_request *request)函数也会对SG初始化赋值,代码就不贴了,所以参数都会在SG中,那SG到底是什么鬼玩意,其实他对应了一个结构体而已,看sapi.h的定义:

[code lang=”c”]
#ifdef ZTS
# define SG(v) ZEND_TSRMG(sapi_globals_id, sapi_globals_struct *, v)
SAPI_API extern int sapi_globals_id;
#else
# define SG(v) (sapi_globals.v)
extern SAPI_API sapi_globals_struct sapi_globals;
#endif

typedef struct {
const char *request_method;
char *query_string;
char *cookie_data;
zend_long content_length;

char *path_translated;
char *request_uri;

/* Do not use request_body directly, but the php://input stream wrapper instead */
struct _php_stream *request_body;

const char *content_type;

zend_bool headers_only;
zend_bool no_headers;
zend_bool headers_read;

sapi_post_entry *post_entry;

char *content_type_dup;

/* for HTTP authentication */
char *auth_user;
char *auth_password;
char *auth_digest;

/* this is necessary for the CGI SAPI module */
char *argv0;

char *current_user;
int current_user_length;

/* this is necessary for CLI module */
int argc;
char **argv;
int proto_num;
} sapi_request_info;

typedef struct _sapi_globals_struct {
void *server_context;
sapi_request_info request_info;
sapi_headers_struct sapi_headers;
int64_t read_post_bytes;
unsigned char post_read;
unsigned char headers_sent;
zend_stat_t global_stat;
char *default_mimetype;
char *default_charset;
HashTable *rfc1867_uploaded_files;
zend_long post_max_size;
int options;
zend_bool sapi_started;
double global_request_time;
HashTable known_post_content_types;
zval callback_func;
zend_fcall_info_cache fci_cache;
} sapi_globals_struct;
[/code]

所以SG(request_info).argv 其实就是sapi_globals_struct结构体request_info下的argv字段

说了这么半天,那扩展中命令行参数到底怎么获取,明白上面原理就很简单啦 如下:

[code lang=”c”]
char ** argv = SG(request_info).argv;
printf("%s", argv[0]);
printf("%s", argv[1]);
printf("%s", argv[2]);
[/code]

去试试看吧,另外如果你想获取 选项参数,类似与 php example.php -f “value for f” 要获取-f 和后面的值 在扩展中可以用,不过我没验证,我看到php_cli文件中是这么用的,扩展中应该也可以。

c = php_getopt(argc, argv, OPTIONS, &php_optarg, &php_optind, 0, 2)

发表评论

电子邮件地址不会被公开。 必填项已用*标注