在PHP7中本地配置多个脚本

时间:2017-06-10 13:14:18

标签: php profiling php-7

自PHP 7发布以来,现在无法使用基本文件中的declare(ticks=1)分析整个脚本选择,然后使用register_tick_function()监视每个标记,因为它不再包含路径。根据{{​​3}}提交的PHP错误,这将永远不会再在PHP 7中提供。

  

由于实现错误,declare(ticks = 1)指令泄漏到PHP 7.0之前的不同编译单元中。这不是每个文件或每个范围的declare()指令应该如何工作。

使用PHP 7中可用的本机PHP(不是C或梨扩展等),这种方法是否有任何替代方法,这将允许我分析页面加载中调用的每个函数或文件,获取详细信息。至少是实际文件路径。

我可以在https://bugs.php.net/bug.php?id=71448找到导致发现错误的原始问题,现在这个问题是关于替代方法的问题。

1 个答案:

答案 0 :(得分:2)

在没有declare(ticks=1)的情况下执行此操作的一种常用方法是使用分析器。分析器将注意到任何方法/函数,被调用的文件等,甚至可以获取定时信息,因此您不仅可以说出何时以及通过什么代码和哪些文件被打开而调用了哪个函数该计划的哪一部分需要多长时间。

PHP中一个着名的分析器附带着名的 Xdebug扩展。它还附带一个调试器:

一个好处是您不需要更改代码来进行分析,这只是您需要采用的PHP配置,因此您可以根据需要打开和关闭它(例如调试/分析)会话)。

PHP Userland(滴答功能)

作为一种解决方法,在每个文件的开头(#71448之后)没有declare(ticks=1);,可以通过协议(用于本地文件系统中常见的文件),用于注入它。

通过创建在文件协议上注册以代理标准文件i / o操作的流包装器,这在技术上是可行的。在这个PoC (Gist on Github)中,显示了最小的实现,以证明它适用于包含。当执行test.php并且尽管other.php在磁盘上没有declare(ticks=1);时,在include上调用已注册的tick函数作为回溯的打印显示:

...
tick_handler() called
#0  tick_handler(1) called at [/home/hakre/stream-wrapper-default-files/test.php:18]
#1  tick_handler() called at [/home/hakre/stream-wrapper-default-files/other.php:2]
#2  include(/home/hakre/stream-wrapper-default-files/other.php) called at [/home/hakre/stream-wrapper-default-files/test.php:24]
...

输出是从注册的tick功能(此处:test.php)生成的:

<?php
/**
 * Inject declare ticks on include
 */
declare(ticks=1);

require __DIR__ . '/streamwrapper.php';

FileStreamWrapper::init();

// using a function as the callback
register_tick_function('tick_handler', true);


// Function which is called on each tick-event
function tick_handler()
{
    echo "tick_handler() called\n";
    debug_print_backtrace();
}

register_tick_function('tick_handler');

include "other.php";
include "another.php"; # file does not exists

stream wrapper in the gist example只为实现两个include语句所需的工作量尽可能少,因为PHP脚本通常需要根据需要进行更多的文件i / o扩展。当它寻求等时,需要考虑动态插入等,但每个文件操作(句柄)都有状态,因为每个文件都有一个实例,所以这应该被很好地封装。全局状态用于为每个操作注册/取消注册流包装器以代理到真实文件系统函数中,否则它会创建无限递归(包装器使用包装器使用包装器...)。到目前为止,PoC原型上展示了它的工作原理。

这也可以(错误地)用于其他事情,但是这个PoC适用于您的特定声明标记并包含用例。