@@ -51,14 +51,28 @@ ZEND_DECLARE_MODULE_GLOBALS(node_php_embed);
5151class node_php_embed ::PhpRequestWorker : public AsyncMessageWorker {
5252 public:
5353 PhpRequestWorker (Nan::Callback *callback, v8::Local<v8::String> source,
54- v8::Local<v8::Object> stream, v8::Local<v8::Value> init_func)
55- : AsyncMessageWorker(callback), result_(), stream_(), init_func_() {
54+ v8::Local<v8::Object> stream, v8::Local<v8::Array> args,
55+ v8::Local<v8::Value> init_func)
56+ : AsyncMessageWorker(callback), result_(), stream_(), init_func_(),
57+ argc_ (args->Length ()), argv_(new char *[args->Length ()]) {
5658 JsStartupMapper mapper (this );
5759 source_.Set (&mapper, source);
5860 stream_.Set (&mapper, stream);
5961 init_func_.Set (&mapper, init_func);
62+ // Turn the JS array into a char** suitable for PHP.
63+ for (uint32_t i = 0 ; i < argc_; i++) {
64+ Nan::Utf8String s (
65+ Nan::Get (args, i)
66+ .FromMaybe (static_cast < v8::Local<v8::Value> >(Nan::EmptyString ())));
67+ argv_[i] = strdup (*s ? *s : " " );
68+ }
69+ }
70+ virtual ~PhpRequestWorker () {
71+ for (uint32_t i = 0 ; i < argc_; i++) {
72+ free (argv_[i]);
73+ }
74+ delete[] argv_;
6075 }
61- virtual ~PhpRequestWorker () { }
6276 const Value &GetStream () { return stream_; }
6377 const Value &GetInitFunc () { return init_func_; }
6478
@@ -67,6 +81,8 @@ class node_php_embed::PhpRequestWorker : public AsyncMessageWorker {
6781 // should go on `this`.
6882 void Execute (MapperChannel *channel TSRMLS_DC) override {
6983 TRACE (" > PhpRequestWorker" );
84+ SG (request_info).argc = argc_;
85+ SG (request_info).argv = argv_;
7086 if (php_request_startup (TSRMLS_C) == FAILURE) {
7187 Nan::ThrowError (" can't create request" );
7288 return ;
@@ -117,6 +133,8 @@ class node_php_embed::PhpRequestWorker : public AsyncMessageWorker {
117133 NODE_PHP_EMBED_G (channel) = nullptr ;
118134 TRACE (" - request shutdown" );
119135 php_request_shutdown (nullptr );
136+ SG (request_info).argc = 0 ;
137+ SG (request_info).argv = nullptr ;
120138 TRACE (" < PhpRequestWorker" );
121139 }
122140 // Executed when the async work is complete.
@@ -138,6 +156,8 @@ class node_php_embed::PhpRequestWorker : public AsyncMessageWorker {
138156 Value result_;
139157 Value stream_;
140158 Value init_func_;
159+ uint32_t argc_;
160+ char **argv_;
141161};
142162
143163/* PHP extension metadata */
@@ -291,20 +311,24 @@ NAN_METHOD(request) {
291311 if (!info[1 ]->IsObject ()) {
292312 return Nan::ThrowTypeError (" stream expected" );
293313 }
294- if (!info[2 ]->IsFunction ()) {
295- return Nan::ThrowTypeError (" init function expected" );
314+ if (!info[2 ]->IsArray ()) {
315+ return Nan::ThrowTypeError (" argument array expected" );
296316 }
297317 if (!info[3 ]->IsFunction ()) {
318+ return Nan::ThrowTypeError (" init function expected" );
319+ }
320+ if (!info[4 ]->IsFunction ()) {
298321 return Nan::ThrowTypeError (" callback expected" );
299322 }
300323 v8::Local<v8::String> source = info[0 ].As <v8::String>();
301324 v8::Local<v8::Object> stream = info[1 ].As <v8::Object>();
302- v8::Local<v8::Value> init_func = info[2 ];
303- Nan::Callback *callback = new Nan::Callback (info[3 ].As <v8::Function>());
325+ v8::Local<v8::Array> args = info[2 ].As <v8::Array>();
326+ v8::Local<v8::Value> init_func = info[3 ];
327+ Nan::Callback *callback = new Nan::Callback (info[4 ].As <v8::Function>());
304328
305329 node_php_embed_ensure_init ();
306330 Nan::AsyncQueueWorker (new PhpRequestWorker (callback, source, stream,
307- init_func));
331+ args, init_func));
308332 TRACE (" <" );
309333}
310334
@@ -367,9 +391,7 @@ static void node_php_embed_ensure_init(void) {
367391 }
368392 TRACE (" >" );
369393 node_php_embed_inited = true ;
370- char *argv[] = { nullptr };
371- int argc = 0 ;
372- php_embed_init (argc, argv PTSRMLS_CC);
394+ php_embed_init (0 , nullptr PTSRMLS_CC);
373395 // Shutdown the initially-created request; we'll create our own request
374396 // objects inside PhpRequestWorker.
375397 php_request_shutdown (nullptr );
0 commit comments