Skip to content

Commit 4f5a23c

Browse files
committed
Add the ability to execute PHP startup code before each request.
1 parent 3ec1589 commit 4f5a23c

File tree

5 files changed

+54
-6
lines changed

5 files changed

+54
-6
lines changed

lib/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ var bindingPath =
55
binary.find(path.resolve(path.join(__dirname, '..', 'package.json')));
66
var bindings = require(bindingPath);
77
bindings.setIniPath(path.join(__dirname, 'php.ini'));
8+
bindings.setStartupFile(path.join(__dirname, 'startup.php'));
89

910
var packageJson = require('../package.json');
1011
var Promise = require('prfun');

lib/startup.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?php
2+
// Startup code for PHP request. This is a good place to implement
3+
// helpers which are easier to write in PHP than in C.
4+
namespace Js;
5+
6+
?>

src/node_php_embed.cc

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ using node_php_embed::node_php_jsobject_call_method;
3636

3737
static void node_php_embed_ensure_init(void);
3838

39+
static char *node_php_embed_startup_file;
40+
3941
ZEND_DECLARE_MODULE_GLOBALS(node_php_embed);
4042

4143
/* PHP extension metadata */
@@ -219,12 +221,23 @@ static void node_php_embed_register_server_variables(
219221

220222
NAN_METHOD(setIniPath) {
221223
TRACE(">");
222-
REQUIRE_ARGUMENT_STRING(0, iniPath);
224+
REQUIRE_ARGUMENT_STRING(0, ini_path);
223225
if (php_embed_module.php_ini_path_override) {
224226
free(php_embed_module.php_ini_path_override);
225227
}
226228
php_embed_module.php_ini_path_override =
227-
(*iniPath) ? strdup(*iniPath) : nullptr;
229+
(*ini_path) ? strdup(*ini_path) : nullptr;
230+
TRACE("<");
231+
}
232+
233+
NAN_METHOD(setStartupFile) {
234+
TRACE(">");
235+
REQUIRE_ARGUMENT_STRING(0, file_name);
236+
if (node_php_embed_startup_file) {
237+
free(node_php_embed_startup_file);
238+
}
239+
node_php_embed_startup_file =
240+
(*file_name) ? strdup(*file_name) : nullptr;
228241
TRACE("<");
229242
}
230243

@@ -256,7 +269,8 @@ NAN_METHOD(request) {
256269

257270
node_php_embed_ensure_init();
258271
Nan::AsyncQueueWorker(new PhpRequestWorker(callback, source, stream,
259-
args, server_vars, init_func));
272+
args, server_vars, init_func,
273+
node_php_embed_startup_file));
260274
TRACE("<");
261275
}
262276

@@ -330,6 +344,7 @@ static void node_php_embed_ensure_init(void) {
330344

331345
NAN_MODULE_INIT(ModuleInit) {
332346
TRACE(">");
347+
node_php_embed_startup_file = NULL;
333348
php_embed_module.php_ini_path_override = nullptr;
334349
php_embed_module.php_ini_ignore = true;
335350
php_embed_module.php_ini_ignore_cwd = true;
@@ -351,6 +366,7 @@ NAN_MODULE_INIT(ModuleInit) {
351366

352367
// Export functions
353368
NAN_EXPORT(target, setIniPath);
369+
NAN_EXPORT(target, setStartupFile);
354370
NAN_EXPORT(target, request);
355371
TRACE("<");
356372
}
@@ -364,6 +380,11 @@ void ModuleShutdown(void *arg) {
364380
php_embed_shutdown(TSRMLS_C);
365381
if (php_embed_module.php_ini_path_override) {
366382
free(php_embed_module.php_ini_path_override);
383+
php_embed_module.php_ini_path_override = NULL;
384+
}
385+
if (node_php_embed_startup_file) {
386+
free(node_php_embed_startup_file);
387+
node_php_embed_startup_file = NULL;
367388
}
368389
TRACE("<");
369390
}

src/phprequestworker.cc

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ extern "C" {
1414
#include "Zend/zend_interfaces.h"
1515
#include "ext/standard/head.h"
1616
#include "ext/standard/info.h"
17+
#include "ext/standard/php_string.h"
1718
}
1819

1920
#include "src/asyncmessageworker.h"
@@ -27,10 +28,11 @@ PhpRequestWorker::PhpRequestWorker(Nan::Callback *callback,
2728
v8::Local<v8::Object> stream,
2829
v8::Local<v8::Array> args,
2930
v8::Local<v8::Object> server_vars,
30-
v8::Local<v8::Value> init_func)
31+
v8::Local<v8::Value> init_func,
32+
const char *startup_file)
3133
: AsyncMessageWorker(callback), result_(), stream_(), init_func_(),
3234
argc_(args->Length()), argv_(new char*[args->Length()]),
33-
server_vars_() {
35+
server_vars_(), startup_file_(startup_file) {
3436
JsStartupMapper mapper(this);
3537
source_.Set(&mapper, source);
3638
stream_.Set(&mapper, stream);
@@ -126,6 +128,22 @@ void PhpRequestWorker::Execute(MapperChannel *channel TSRMLS_DC) {
126128
{
127129
ZVal source{ZEND_FILE_LINE_C}, result{ZEND_FILE_LINE_C};
128130
zend_first_try {
131+
// First execute startup code.
132+
if (startup_file_) {
133+
int nlen = 0;
134+
char *f = php_addslashes(const_cast<char*>(startup_file_),
135+
strlen(startup_file_),
136+
&nlen, 0 TSRMLS_CC);
137+
char *buf = new char[11 + nlen];
138+
char startup_msg[] = { "startup" };
139+
nlen = snprintf(buf, 11 + nlen, "require '%s'", f);
140+
zend_eval_stringl_ex(buf, nlen, *result, startup_msg, false
141+
TSRMLS_CC);
142+
result.SetNull();
143+
delete[] buf;
144+
efree(f);
145+
}
146+
// Now execute the user's source.
129147
char eval_msg[] = { "request" }; // This shows up in error messages.
130148
source_.ToPhp(channel, source TSRMLS_CC);
131149
assert(Z_TYPE_P(*source) == IS_STRING);

src/phprequestworker.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ class PhpRequestWorker : public AsyncMessageWorker {
2424
PhpRequestWorker(Nan::Callback *callback, v8::Local<v8::String> source,
2525
v8::Local<v8::Object> stream, v8::Local<v8::Array> args,
2626
v8::Local<v8::Object> server_vars,
27-
v8::Local<v8::Value> init_func);
27+
v8::Local<v8::Value> init_func,
28+
const char *startup_file);
2829
virtual ~PhpRequestWorker();
2930
const inline Value &GetStream() { return stream_; }
3031
const inline Value &GetInitFunc() { return init_func_; }
@@ -50,6 +51,7 @@ class PhpRequestWorker : public AsyncMessageWorker {
5051
uint32_t argc_;
5152
char **argv_;
5253
std::unordered_map<std::string, std::string> server_vars_;
54+
const char *startup_file_;
5355
};
5456

5557
} // namespace node_php_embed

0 commit comments

Comments
 (0)