@@ -10,7 +10,9 @@ Node/iojs >= 2.4.0 is currently required, since we use `NativeWeakMap`s
1010in the implementation. This could probably be worked around using
1111v8 hidden properties, but it doesn't seem worth it right now.
1212
13- # USAGE
13+ # Usage
14+
15+ ## Basic
1416
1517``` js
1618var path = require (' path' );
@@ -23,6 +25,35 @@ php.request({
2325});
2426```
2527
28+ ## Advanced
29+
30+ ``` js
31+ var php = require (' php-embed' );
32+ php .request ({
33+ source: [' call_user_func(function() {' ,
34+ ' class Foo {' ,
35+ ' var $bar = "bar";' ,
36+ ' }' ,
37+ ' $c = $_SERVER["CONTEXT"];' ,
38+ ' // Invoke an Async JS method' ,
39+ ' $result = $c->jsfunc(new Foo, $c->jsvalue, new Js\\ Wait);' ,
40+ ' // And return the value back to JS.' ,
41+ ' return $result;' ,
42+ ' })' ].join (' \n ' ),
43+ context: {
44+ jsvalue: 42 , // Pass JS values to PHP
45+ jsfunc : function (foo , value , cb ) {
46+ // Access PHP object from JS
47+ console .log (foo .bar , value); // Prints "bar 42"
48+ // Asynchronous completion, doesn't block node event loop
49+ setTimeout (function () { cb (null , " done" ) }, 500 );
50+ }
51+ }
52+ }).then (function (v ) {
53+ console .log (v); // Prints "done" ($result from PHP)
54+ }).done ();
55+ ```
56+
2657# API
2758
2859## php.request(options, [ callback] )
@@ -33,15 +64,33 @@ parameter.
3364* ` options ` : a hash containing various parameters for the request.
3465 Either ` source ` or ` file ` is mandatory; the rest are optional.
3566 - ` source ` :
36- Specifies a source string to evaluate in the request context.
67+ Specifies a source string to evaluate * as an expression* in
68+ the request context. (If you want to evaluate a statement,
69+ you can wrap it in ` call_user_func(function () { ... }) ` .)
3770 - ` file ` :
3871 Specifies a PHP file to evaluate in the request context.
3972 - ` stream ` :
40- A node ` stream.Writable ` to accept output from the PHP request.
41- If not specified, defaults to ` process.stdout ` .
73+ A node ` stream.Writable ` to accept output from the PHP
74+ request. If not specified, defaults to ` process.stdout ` .
75+ - ` request ` :
76+ If an ` http.IncomingMessage ` is provided here, the PHP
77+ server variables will be set up with information about
78+ the request.
79+ - ` args ` :
80+ If an array with at least one element is provided, the
81+ PHP ` $argc ` and ` $argv ` variables will be set up as
82+ PHP CLI programs expect. Note that ` args[0] ` should
83+ be the "script file name", as in C convention.
4284 - ` context ` :
4385 A JavaScript object which will be made available to the PHP
4486 request in ` $_SERVER['CONTEXT'] ` .
87+ - ` serverInitFunc ` :
88+ The user can provide a JavaScript function which will
89+ be passed an object containing values for the PHP
90+ [ ` $_SERVER ` ] ( http://php.net/manual/en/reserved.variables.server.php )
91+ variable, such as ` REQUEST_URI ` , ` SERVER_ADMIN ` , etc.
92+ You can add or override values in this function as needed
93+ to set up your request.
4594* ` callback ` * (optional)* : A standard node callback. The first argument
4695 is non-null if an exception was raised. The second argument is the
4796 result of the PHP evaluation, converted to a string.
@@ -102,7 +151,63 @@ of reading the file.
102151Note that calls using ` Js\Wait ` block the PHP thread but do not
103152block the node thread.
104153
105- # INSTALLING
154+ # Javascript API
155+
156+ The JavaScript ` in ` operator, when applied to a wrapped PHP object,
157+ works the same as the PHP ` isset() ` function. Similarly, when applied
158+ to a wrapped PHP object, JavaScript ` delete ` works like PHP ` unset ` .
159+
160+ ``` js
161+ var php = require (' php-embed' );
162+ php .request ({
163+ source: ' call_user_func(function() {' +
164+ ' class Foo { var $bar = null; var $bat = 42; } ' +
165+ ' $_SERVER["CONTEXT"](new Foo()); ' +
166+ ' })' ,
167+ context : function (foo ) {
168+ console .log (" bar" in foo ? " yes" : " no" ); // This prints "no"
169+ console .log (" bat" in foo ? " yes" : " no" ); // This prints "yes"
170+ }
171+ }).done ();
172+ ```
173+
174+ PHP has separate namespaces for properties and methods, while JavaScript
175+ has just one. Usually this isn't an issue, but if you need to you can use
176+ a leading ` $ ` to specify a property, or ` __call ` to specifically invoke a
177+ method.
178+
179+ ``` js
180+ var php = require (' php-embed' );
181+ php .request ({
182+ source: [' call_user_func(function() {' ,
183+ ' class Foo {' ,
184+ ' var $bar = "bar";' ,
185+ ' function bar($what) { echo "I am a ", $what, "!\n "; }' ,
186+ ' }' ,
187+ ' $foo = new Foo;' ,
188+ ' // This prints "bar"' ,
189+ ' echo $foo->bar, "\n ";' ,
190+ ' // This prints "I am a function!"' ,
191+ ' $foo->bar("function");' ,
192+ ' // Now try it in JavaScript' ,
193+ ' $_SERVER["CONTEXT"]($foo);' ,
194+ ' })' ].join (' \n ' ),
195+ context : function (foo ) {
196+ // This prints "bar"
197+ console .log (foo .$bar );
198+ // This prints "I am a function"
199+ foo .__call (" bar" , " function" );
200+ }
201+ }).done ();
202+ ```
203+
204+ At the moment, all property accesses and method invocations from
205+ JavaScript to PHP are done synchronously; that is, they block the
206+ JavaScript event loop. The mechanisms are in place for asynchronous
207+ access; I just haven't quite figured out what the syntax for that
208+ should look like.
209+
210+ # Installing
106211
107212You can use [ ` npm ` ] ( https://github.com/isaacs/npm ) to download and install:
108213
@@ -117,7 +222,7 @@ version of `node-gyp`, and thus your system must meet
117222It is also possible to make your own build of ` php-embed ` from its
118223source instead of its npm package ([ see below] ( #building-from-the-source ) ).
119224
120- # BUILDING FROM THE SOURCE
225+ # Building from source
121226
122227Unless building via ` npm install ` you will need ` node-pre-gyp `
123228installed globally:
@@ -149,23 +254,41 @@ Developers hacking on the code will probably want to use:
149254
150255Passing the ` --debug ` flag to ` node-pre-gyp ` enables memory checking, and
151256the ` build ` command (instead of ` rebuild ` ) avoids rebuilding ` libphp5 `
152- from scratch after every change.
257+ from scratch after every change. (You can also use `npm run
258+ debug-build` if you find that easier to remember.)
153259
154- # TESTING
260+ # Testing
155261
156- [ mocha ] ( https://github.com/visionmedia/mocha ) is required to run unit tests.
262+ To run the test suite, use:
157263
158- npm install mocha
159264 npm test
160265
266+ This will run the JavaScript and C++ linters, as well as a test suite
267+ using [ mocha] ( https://github.com/visionmedia/mocha ) .
268+
269+ During development, ` npm run jscs-fix ` will automatically correct most
270+ JavaScript code style issues, and ` npm run valgrind ` will detect a
271+ large number of potential memory issues. Note that node itself will
272+ leak a small amount of memory from ` node::CreateEnvironment ` ,
273+ ` node::cares_wrap::Initialize ` , and ` node::Start ` ; these can safely be
274+ ignored in the ` valgrind ` report.
161275
162- # CONTRIBUTORS
276+ # Contributors
163277
164278* [ C. Scott Ananian] ( https://github.com/cscott )
165279
166- # RELATED PROJECTS
280+ # Related projects
281+
282+ * [ ` node-mediawiki-express ` ] ( https://github.com/cscott/node-mediawiki-express )
283+ uses ` php-embed ` to run mediawiki inside a node.js express server.
284+ * [ ` v8js ` ] ( https://github.com/preillyme/v8js ) is a "mirror image"
285+ project: it embeds the v8 JavaScript engine inside of PHP, whereas
286+ ` php-embed ` embeds PHP inside node/v8. The author of ` php-embed `
287+ is a contributor to ` v8js ` and they share bits of code. The
288+ JavaScript API to access PHP objects is deliberately similar
289+ to that used by ` v8js ` .
167290
168- # LICENSE
291+ # License
169292Copyright (c) 2015 C. Scott Ananian.
170293
171294` node-php-embed ` is licensed using the same
0 commit comments