DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Newsletter
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Related

  • These 37 Items Are Required for Magento 2 Launch
  • The Role of JavaScript in Front-End and Back-End Development
  • PHP vs React
  • A Beginner's Guide to Back-End Development

Trending

  • Testing Java and Spring Applications With Kotlin: Low-Risk to Adoption
  • Fix the Target, Precompute Once: A Backend-Free Word-Ladder Solver With a BFS Distance Field
  • Gen AI Debugging Tools Compared: Genkit vs Vercel AI SDK vs Mastra
  • Agent Harness, Memory Indexing, and AI Governance in Test Automation

Draft This article hasn't been published, so readers can't see it.

In moderation This article is waiting for review, so readers can't see it yet.

Deleted This article has been deleted, so readers can't see it.

  1. DZone
  2. Coding
  3. Languages
  4. Running JavaScript inside PHP code

Running JavaScript inside PHP code

By 
Giorgio Sironi
·
Feb. 29, 12 · Tutorial
Post on X (opens in a new tab) Share on LinkedIn (opens in a new tab)
52.8K Views

Join the DZone community Save articles, join the discussion, and download Refcards and Trend Reports with a free account.

Join for free Already a member? Log in

v8js is a new PHP extension able to run JavaScript code inside V8, Google's JavaScript interpreter that powers for example Chrome and NodeJS.

This extension is highly alpha - and its API would probably change in the months ahead. Since documentation is lacking, I invite you to repeat the discovering process I follow in this post in case you find some differences in a new version of v8js.

Installation

V8 must be present on the machine in order to install the extension. On a Debian/Ubuntu system, run the following:

sudo apt-get install libv8-dev libv8-dbg

libv8-dev will also install libv8 in its latest version.

Afterwards, download and compile the extension with:

sudo pecl install v8js

There are no more requirements for compilation apart from the usual dependencies for PECL packages, like build-essential.

After that, add:

extension=v8js.so

to php.ini or to a section in conf.d.

$ php -m | grep v8
v8js

will confirm you the extension is loaded.

Some introspection

PHP's reflection let us take a look at the classes and methods provided by this extension, even without documentation available. It probably hasn't been written yet, due to the unstable API.

$ php -r 'var_dump(get_declared_classes());' | grep V8
  string(8) "V8Object"
  string(10) "V8Function"
  string(4) "V8Js"
  string(13) "V8JsException"
$ php -r '$class = new ReflectionClass("V8Js"); var_dump($class->getMethods());'
array(5) {
  [0]=>
  &object(ReflectionMethod)#2 (2) {
    ["name"]=>
    string(11) "__construct"
    ["class"]=>
    string(4) "V8Js"
  }
  [1]=>
  &object(ReflectionMethod)#3 (2) {
    ["name"]=>
    string(13) "executeString"
    ["class"]=>
    string(4) "V8Js"
  }
  [2]=>
  &object(ReflectionMethod)#4 (2) {
    ["name"]=>
    string(19) "getPendingException"
    ["class"]=>
    string(4) "V8Js"
  }
  [3]=>
  &object(ReflectionMethod)#5 (2) {
    ["name"]=>
    string(17) "registerExtension"
    ["class"]=>
    string(4) "V8Js"
  }
  [4]=>
  &object(ReflectionMethod)#6 (2) {
    ["name"]=>
    string(13) "getExtensions"
    ["class"]=>
    string(4) "V8Js"
  }
}
$ php -r '$v8 = new V8Js(); var_dump($v8->executeString("1+2+3"));'
int(6)

Interesting! We have just executed our first JavaScript expression inside a PHP process. Apparently the last statement's value is returned by the executeString() method, with a rough conversion preserving the type:

$ php -r '$v8 = new V8Js(); var_dump($v8->executeString("var obj = {}; obj.field = 1; obj.field++; obj.field;"));'
int(2)

Syntax or runtime errors are signaled with a V8JsException:

$ php -r '$v8 = new V8Js(); var_dump($v8->executeString("var obj = {"));'
PHP Fatal error:  Uncaught exception 'V8JsException' with message 'V8Js::executeString():1: SyntaxError: Unexpected end of input' in Command line code:1
Stack trace:
#0 Command line code(1): V8Js->executeString('var obj = {')
#1 {main}
  thrown in Command line code on line 1

Let's add more difficulty

The FizzBuzz kata OO solution is an example of JavaScript code creating an object and executing anonymous functions: it's a good test bench for our integration.Since evaluating a variable as the last line returns it, that is our channel of communication, supporting integers, strings, floats, booleans, arrays (not objects at this time). Meanwhile, input for JavaScript code can be embedded into the executed string.

This code will output string(8) "FizzBuzz":

<?php
$javaScriptCode = '
function FizzBuzz(correspondences) {
    this.correspondences = correspondences;
    this.accept = function (number) {
        var result = ""
        for (var divisor in this.correspondences) {
            if (number % divisor == 0) {
                result = result + this.correspondences[divisor];
            }
        }
        if (result) {
            return result;
        } else {
            return number;
        }
    }
}
var myFizzBuzz = new FizzBuzz({3 : "Fizz", 5 : "Buzz"});
myFizzBuzz.accept(15);
';
$v8 = new V8Js();
var_dump($v8->executeString($javaScriptCode));

By changing it a bit, we can build a JSON string by backslashing the double quotes ("), and returns it in lieu of an object to communicate to the PHP process a complex result:

...
var myFizzBuzz = new FizzBuzz({3 : "Fizz", 5 : "Buzz"});
"{\"15\" : \"" + myFizzBuzz.accept(15) + "\", \"5\" : \"" + myFizzBuzz.accept(5) + "\"}";
';
$v8 = new V8Js();
$result = $v8->executeString($javaScriptCode);
var_dump($result);
var_dump(json_decode($result));

The output is:

string(33) "{"15" : "FizzBuzz", "5" : "Buzz"}"
object(stdClass)#2 (2) {
  ["15"]=>
  string(8) "FizzBuzz"
  ["5"]=>
  string(4) "Buzz"
}

Wiring

Executing an external script would be nice: it would provide better stack traces, with traceable line numbers at the JavaScript level. It would also mean we won't need backslashing for single quotes, simplifying the syntax.

We cannot load scripts on the JavaScript side out of the box, due to V8 missing this functionality (Node JS adds this feature) but we can load the code on the PHP Side:

// test.js
$ php loadingfiles.php
string(24) "test.js file was loaded."
// loadingfiles.php
<?php
$javascriptCode = file_get_contents("test.js");
$v8 = new V8Js();
$result = $v8->executeString($javascriptCode);
var_dump($result);

Execution results in:

$ php loadingfiles.php
string(24) "test.js file was loaded."

However, we still miss the capability of including JavaScript libraries.

Conclusion

There are many possible use cases for v8js, like sandboxed scripting or the integration of some code which was written for the client side. That would not be the most clean solution, but it's a Turing complete approach, so why not?

After all, it's already possible to run PHP on Java or Python and Ruby on .NET. JavaScript is becoming ubiquitous, so why not providing support for it, even in a caged box?

PHP JavaScript

Opinions expressed by DZone contributors are their own.

Related

  • These 37 Items Are Required for Magento 2 Launch
  • The Role of JavaScript in Front-End and Back-End Development
  • PHP vs React
  • A Beginner's Guide to Back-End Development

Partner Resources

×

Comments

Loading comments

The comments didn't load

Please try again in a moment.

Likes

Loading

The next likes didn't load. Please try again.

The likes didn't load

Please try again in a moment.

See who liked this

Log in or join DZone for free to see who liked this article.

Log in Join for free
  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook