这是可能的!使用问题中提到的两个库,剖析
babel-preset-php
并重用一些部分将PHP转换为Javascript,然后对Javascript进行求值。这是一个工作演示,请随意在
<textearea>
和媒体
run
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>
下面是用于生成
php.js
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);
};