【问题标题】:Get PHP Opcodes Dynamically at Runtime在运行时动态获取 PHP 操作码
【发布时间】:2015-03-10 08:29:24
【问题描述】:

我想构建一个 PHP 扩展,它可以动态检查从 PHP 文件生成的每个操作码并对其进行一些检查。

我遇到了几个网站,发现了几个像zend_set_user_opcode_handler 这样的函数,但我不明白如何使用这个函数来获得像ASSIGN !0, 50 这样的完整操作码。

我知道像 php -d vld.active=1 -d vld.execute=0 -f [filename].php 这样的命令可以用来生成 PHP 操作码,但据我所知,您只能在 PHP 程序终止后访问操作码。

我想从扩展中得到一个操作码,它是在函数执行时一个接一个(动态地)获得的。

有人可以帮我解决这个问题吗?

【问题讨论】:

  • 我希望 xdebug 会做类似的事情,你能看看代码吗?
  • 生成操作码相当困难,因为这样做的所有东西都标记为static,并且只能在zend_compile.c中使用,所以你必须复制它。
  • 可能有更多的外观来构建一个 AST。
  • 不确定我完全理解你想要什么,但如果你想在操作码级别逐步执行代码(并显示执行的操作码),那么 phpdbg 支持。
  • 检查this out,应该有帮助

标签: php zend-framework php-extension php-internals


【解决方案1】:

您可以使用通过 pecl 获得的parsekit,可以从pecl website 下载或安装:

sudo pecl install parsekit

在运行时从一串 PHP 代码中获取 OPcodes:

您可以使用parsekit_compile_string

这个命令的语法是:

array parsekit_compile_string ( string $phpcode [, array &$errors [, int $options = PARSEKIT_QUIET ]] )

参数:

phpcode

包含 phpcode 的字符串。类似于 eval() 的参数。

错误

编译期间遇到的错误(包括致命错误)的 2D 散列。通过引用返回。

选项

PARSEKIT_QUIET 或 PARSEKIT_SIMPLE 之一。在返回的输出中产生不同程度的详细信息。

返回值

返回一个复杂的多层数组结构,详情如下。

这个例子的用法是:

<?php
  $ops = parsekit_compile_string('
echo "Foo\n";
', $errors, PARSEKIT_QUIET);

  var_dump($ops);
?>

输出太长,无法包含在此答案中,但可在 documentation page 上找到


在运行时从 PHP 文件中获取 OPcodes:

您可以使用parsekit_compile_file

与上述方法非常相似,但解析的是文件而不是字符串。

【讨论】:

    猜你喜欢
    • 2010-12-01
    • 2010-12-20
    • 2011-03-05
    • 2018-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-30
    相关资源
    最近更新 更多