This is not another of those questions, this is about parsing and interpreting PHP in the browser with JS.
How can you run PHP in JavaScript? I am not asking about running PHP in the server and then send the resulting string to the browser as JavaScript. I am literally talking about JavaScript parsing and running PHP.
This might be useful in many places:
I've searched around and found php-parser
and babel-preset-php
, but nothing to run it. Ideally I'm looking for something like this, though I couldn't find anything through Google/SO/etc:
// No server needed, "just" Javascript parsing PHP
alert(php(`<?= "Hello world" ?>`));
If you know a better way than my own answer, please feel free to share it! I'm very curious about what the community thinks.
It is possible! Using the two libraries mentioned in the question, dissect babel-preset-php
and reuse some parts to transpile PHP to Javascript, and then eval the Javascript. Here is a working demo, feel free to write some basic PHP in the <textearea>
and press run
to run the PHP in the browser:
const $ = sel => document.querySelector(sel);
$('#horrible').addEventListener('submit', e => {
e.preventDefault();
eval($('#horrible textarea').value);
});
body, html {
margin: 0;
}
textarea {
line-height: 1.5;
margin: 0;
height: 2.1em;
padding: .3em .6em;
border: 1px solid #ccc;
background-color: #fff;
border-radius: .2em;
transition: all 0.3s;
width: 90%;
}
button {
display: inline-block;
text-align: center;
margin: 0;
padding: .3em .9em;
vertical-align: middle;
background: #0074d9;
color: #fff;
border: 0;
border-radius: .2em;
width: auto;
user-select: none;
margin: .3em 0;
cursor: pointer;
transition: all 0.3s;
border-radius: .2em;
height: auto;
box-shadow: 0 0 rgba(0,0,0,0) inset;
}
<form id="horrible">
<textarea style="min-height:150px">const vars = { icon: '🎉' };
const out = php(`<?= "for fun! ".$icon ?>`, vars);
alert(out);</textarea>
<button data-tooltip="Are you sure? Like, 100%? There is no coming back">EVAL()</button>
<script src="https://francisco.io/blog/running-php-in-javascript/php.min.js"></script>
Here is the actual code snippet used to build the php.js
file linked above:
import parser from 'php-parser';
import translator from './translator';
import generator from '@babel/generator';
const run = (code, opts) => {
// Make a closure so that `out` doesn't collide with the PHP variables:
let out = '';
// Define `echo` since it's used in the transpiled JS code for some reason
opts.echo = opts.echo || (str => out += str);
// Pretend this is safe. Pro tip: IT IS NOT SAFE
new Function(...Object.keys(opts), code)(...Object.values(opts));
return out;
}
export default function (src, opts = {}) {
const ast = new parser().parseCode(src);
const file = translator.translateProgram(ast);
const code = generator(file).code;
return run(code, opts);
};