pwt777/phpexecjs

从 PHP 运行 JavaScript 代码

v3.1.0 2021-12-23 09:59 UTC

README

PhpExecJS 允许您从 PHP 运行 JavaScript 代码。

简例

print_r($phpexecjs->evalJs("'red yellow blue'.split(' ')"));

将打印

Array
(
    [0] => red
    [1] => yellow
    [2] => blue
)

Build Status Latest Stable Version Latest Unstable Version License

安装

composer require nacmartin/phpexecjs

示例程序

用法

<?php
    require __DIR__ . '/../vendor/autoload.php';
    
    use Nacmartin\PhpExecJs\PhpExecJs;
    
    $phpexecjs = new PhpExecJs();
    
    print_r($phpexecjs->evalJs("'red yellow blue'.split(' ')"));

将打印

Array
(
    [0] => red
    [1] => yellow
    [2] => blue
)

使用上下文

您可以设置一个上下文,如库等,您希望在您的 eval'd 代码中使用。例如,ReactBundle 使用此功能在服务器端渲染 React。

例如,我们可以使用此功能编译 CoffeeScript

    $phpexecjs->createContextFromFile("https://coffeescript.node.org.cn/extras/coffee-script.js");
    print_r($phpexecjs->call("CoffeeScript.compile", ["square = (x) -> x * x", ['bare' => true]]));


That will print:

      var square;
    
      square = function(x) {
        return x * x;
      };

您可以将此示例扩展以执行类似使用此函数作为上下文的事情

    $square = $phpexecjs->call("CoffeeScript.compile", ["square = (x) -> x * x", ['bare' => true]]);
    $phpexecjs->createContext($square);
    print_r($phpexecjs->evalJs('square(3)'));

这将打印 9

这可以用于例如,使用 CoffeeScript 或在 JavaScript 模板语言中编译模板。

它是如何工作的

当您运行 evalJs 时,代码将被插入到一个用于运行 JavaScript 的 eval() 的小包装器中,并检查状态以进行错误处理。

如果您设置了上下文,则代码将在 JavaScript 中的 eval() 调用之前插入,并且如果您已安装 V8Js 扩展,则它将预编译它。

支持的运行时

默认情况下,PhPExecjs 将自动检测最佳可用运行时。目前支持的运行时包括

建议安装 V8Js,但您可能希望在生产环境中安装它,同时在开发过程中仍然能够使用 PhpExecJs 调用 node 作为子进程,这样您就不需要安装扩展。

添加外部运行时

如果您有一个外部运行器(比如,Spidermonkey),并且您想使用它,只需将其传递给构造函数即可

    $myRuntime = new ExternalRuntime('My runtime name', 'my_command');
    $phpExecJs = new PhpExecJs($myRuntime);

通过运行时进行贡献

我们希望支持更多运行时(例如,Duktape)。如果您想为运行时做出贡献,这很简单。您只需实现 src/Runtimes/RuntimeInterface。请参阅 src/Runtimes 目录中的示例。

为什么我不能使用像 setTimeout 这样的某些函数?

PhpExecJs 为 JavaScript 运行时提供了一个公共接口,因此它只能运行对解释器无关的代码。因此,某些功能被禁用。值得注意的是,定时器函数被禁用,因为并非所有运行时都保证完整的 JavaScript 事件循环。如果您想使用这些功能中的任何一个,请直接使用 node.js 而不是这个高级库

globalmoduleexportsrequireconsolesetTimeoutsetIntervalclearTimeoutclearIntervalsetImmediateclearImmediate

致谢

这个库受到了 Ruby 库 ExecJs 的启发。

用于管理进程和临时文件的部分代码已被 KNP Labs 的库 Snappy 所采用。