This is a proof-of-concept started at a hackathon recently to see if it could be done. There's some interesting aspects of the two languages that make this a really interesting challenge: lexical scope, prototypal inheritance, duality of
+ operator in JS, PHP's implicit variable declaration, etc. A lot of this had to be implemented in runtime helpers with type checking, but it turns out it's totally doable.
What could this possibly be used for?
There are dozens of "compile to JS" languages available (Coffee, TypeScript, Dart), but not many good choices in the PHP world**. PHP is ubiquitous in bulk hosting, it runs on Google App Engine, AppFog, Rackspace Cloud Sites and virtually every LAMP stack in the world. So if you need to host on PHP but don't like writing PHP, well tough luck. ...unless you could write in JS and deploy to PHP!
What about performance?
Sure, you pay a performance penalty at runtime, but seriously, have you run mainstream PHP apps before? It's not like the performance bar is too high (I think a default WP install runs 27 SQL queries to render the homepage). Your app is likely not CPU bound anyway (and if it is, then you should be running Node + worker processes or some other awesome solution).
At this point I'm focusing on correctness, not performance, and this is very alpha stuff, but it works.
The core language is mostly implemented and has some tests (Object, Array, Math lib, String methods, etc) but there is no interface to the outside world besides
process.exit(). A basic HTTP module is in the works, but there's no file-system or database access and there's no formal way to call into PHP from JS.
Feel free to contribute if this interests you.
How to Use
Install from GitHub:
git clone firstname.lastname@example.org:sstur/js2php.git cd js2php npm install
Install from npm:
npm install -g jstophp
When you install from npm using the
-g flag, you can run it from any directory by simply calling
js2php rather than calling
node path/to/js2php. The rest of the examples in this readme will call it this way.
Compile and run a simple example:
echo 'var x = "world"; console.log("hi " + x)' | js2php --quiet | php
or, a more verbose example:
echo "var a = 1; console.log(a + 1)" > example.js js2php example.js > example.php php example.php
How it works
tools/codegen.js generates the PHP code by walking the tree.
Various constructs get wrapped in helper functions, for instance, property access, method calls and
+ operator. The runtime helpers can be found in
php/helpers and there are a bunch of classes in
php/classes for Array, RegExp and such. All this PHP gets packaged into your output file, or you can save it to a standalone runtime and reference that from your output file like so:
js2php --runtime-only > runtime.php js2php --runtime runtime.php example.js > example.php
You can also specify the output file using
--out and you can compile multiple input files into one output file like so:
js2php -o example.php file1.js file2.js
Have a play with the online demo. The generated code will look something like this:
It's not particularly elegant, but it's human-readable and has all the basics we need to implement standards-compliant JS in PHP.
There are a handful of other compile-to-PHP languages I want to mention. Haxe is probably the most popular and is a solid statically-typed language. I also came across Pharen (a Lisp implementation), gutscript and Mammouth (both similar to CoffeeScript) and Pratphall (TypeScript syntax). There's also another JS to PHP project from a few years back which is written in PHP and a project with the same name as this one which is similar at the parsing level, but somewhat different beyond that (accepts JS syntax but otherwise behaves like PHP). Most of these projects are either incomplete or abandoned which is a shame. I love the idea of writing PHP but in a friendlier language or syntax, and it would be great to see more usable choices in this space!
npm test. Requires PHP 5.3+ or HHVM.
Copyright (c) 2014, email@example.com. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
Neither the name of the author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.