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
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Because the DevOps movement has redefined engineering responsibilities, SREs now have to become stewards of observability strategy.

Apache Cassandra combines the benefits of major NoSQL databases to support data management needs not covered by traditional RDBMS vendors.

The software you build is only as secure as the code that powers it. Learn how malicious code creeps into your software supply chain.

Generative AI has transformed nearly every industry. How can you leverage GenAI to improve your productivity and efficiency?

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

  • Is Big Data Dying?
  • How to Use AWS Aurora Database for a Retail Point of Sale (POS) Transaction System
  • Bridging UI, DevOps, and AI: A Full-Stack Engineer’s Approach to Resilient Systems
  • Can You Run a MariaDB Cluster on a $150 Kubernetes Lab? I Gave It a Shot
  1. DZone
  2. Coding
  3. Languages
  4. Running JavaScript inside PHP code

Running JavaScript inside PHP code

By 
Giorgio Sironi user avatar
Giorgio Sironi
·
Feb. 29, 12 · Tutorial
Likes (0)
Comment
Save
Tweet
Share
52.3K Views

Join the DZone community and get the full member experience.

Join For Free

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
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

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 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!