在 PHP7 中本机分析多个脚本

2024-01-29

自 PHP 7 发布以来,现在不可能使用以下命令来分析整个脚本选择declare(ticks=1)在你的基本文件中,然后使用register_tick_function()监视每个刻度,因为它不再遵循包含路径。根据提交的 PHP 错误https://bugs.php.net/bug.php?id=71448 https://bugs.php.net/bug.php?id=71448这在 PHP 7 中将不再可用。

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

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

我最初发现该错误的问题可以在以下位置找到:如何避免在 PHP 7 中的每个文件上重新声明刻度 https://stackoverflow.com/questions/44440613/how-to-avoid-redeclaring-ticks-on-every-file-in-php-7,这个问题现在是关于替代方法的。


一种常见的方法无需declare(ticks=1)是使用分析器。分析器会注意到any调用的方法/函数、加载的文件等,甚至还可以获取计时信息,这样您不仅可以知道哪个函数在何时、通过什么代码调用以及打开了哪些文件,还可以知道程序的哪一部分花费了多长时间。

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

  • https://xdebug.org/ https://xdebug.org/

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

PHP Userland(勾选函数)

作为一种解决方法,没有declare(ticks=1);在每个文件的开头(之后#71448 https://bugs.php.net/bug.php?id=71448),可以通过流包装器动态添加此内容file注入它的协议(对于本地文件系统中的文件来说很常见)。

通过创建在文件协议上注册的流包装器来代理标准文件 I/O 操作,这在技术上是可行的。在这个PoC(Github 上的要点) https://gist.github.com/hakre/45df61688fb3f6f10101bd2cdb24d0e6显示了最低限度的实现,以证明它适用于包含。什么时候test.php被处决,尽管如此other.php还没有declare(ticks=1);在磁盘上,注册的刻度函数在包含时被调用,如回溯打印所示:

...
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

The gist 示例中的流包装器 https://gist.github.com/hakre/45df61688fb3f6f10101bd2cdb24d0e6#file-streamwrapper-php只实现了两个 include 语句所需的最少内容,因为 PHP 脚本通常会执行更多文件 I/O,因此需要根据需要进行扩展。当它进行查找等时,需要考虑动态插入等。但是每个文件操作(句柄)都有状态,因为每个文件操作都有一个实例,因此应该很好地封装。全局状态用于注册/注销每个操作的流包装器以代理到真实的文件系统函数,否则它会创建无限递归(包装器使用包装器使用包装器...)。到目前为止,PoC 展示了它的原理工作原理。

这也可以(误)用于其他用途,但此 PoC 适用于您的特定声明标记并包含用例。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 PHP7 中本机分析多个脚本 的相关文章

  • 我如何向 Windows Server IIS 7 中的文件夹授予权限

    我是 PHP 和 Windows Server 新手 在查看我在 PHP 中创建的表单时遇到以下错误 Error in exception handler The stream or file C inetpub wwwroot wrp a
  • 管理产品页面自定义字段显示在购物车和结账中

    我在产品页面的常规设置选项卡上的 WooCommerce 管理中创建了一个自定义字段 以插入几天的制造时间 我想在购物车和结帐页面上每个产品名称上方显示此自定义字段值 这是我的代码 Insert a Custom Admin Field f
  • 如何统计订单总价?

    我有这些表 Orders id status user id address id 1 await 1 1 products id name price quantity 1 test1 100 5 2 test2 50 5 order p
  • 如何使用 Laravel 5.3 注销并重定向到登录页面?

    我正在使用 Laravel 5 3 并尝试实现身份验证系统 我用了php artisan命令make auth来设置它 我根据我的布局编辑了视图 并将其重定向到我的仪表板页面而不是主页 在设置中设置为默认值 现在 当我尝试注销时 它向我抛出
  • 如何从循环内的字符串中删除最后一个字符

    我正在尝试在 xml 中的一行中打印所选的不同类别 喜欢
  • 使用 str_replace 使其仅作用于第一个匹配项?

    我想要一个版本str replace 仅替换第一次出现的 search in the subject 有没有一个简单的解决方案 或者我需要一个 hacky 解决方案 虽然没有它的版本 但解决方案一点也不黑 pos strpos haysta
  • 包含 WordPress 之外的 WordPress 内容

    我正在寻找构建 WordPress 网站的移动版本 并将其大部分内置于静态文件中 但我试图从运行移动网站的外部 PHP 文件内部访问 WordPress 内容 如何在不手动编写 SQL 查询的情况下访问循环或数据库 Edit 为了澄清一下
  • StrRev() 不支持 UTF-8 [重复]

    这个问题在这里已经有答案了 我正在尝试编写一个代码来替换非阿拉伯支持的程序中支持的阿拉伯文本因为我需要在替换后反转文本 但它显示一些垃圾内容而不是想要的结果 这是代码 结果 After Reverse 我需要它是原来的样子 但相反 不是垃圾
  • 字符串的渐进单词组合

    我需要获得字符串的渐进单词组合 例如 这是字符串 输出 这是字符串 这是 这个字符串 是字符串 这 是 细绳 你知道类似的算法吗 我需要php语言 谢谢 这是解决您问题的简单代码 我将每个字符串递归地连接到数组中的其余字符串 string
  • 传递表单变量的安全方式

    我正在为我的 WordPress 主题构建联系表单 我希望能够从后端输入接收者地址 目前我正在传递带有隐藏输入字段的变量
  • MySQL ifnull 相当于 php

    我的场景 exTime get cfg var session gc maxlifetime get cfg var session gc maxlifetime 1440 我希望它像 mysql 一样 exTime isnull get
  • 如何使用Google API PHP SDK获取用户信息

    我正在尝试为拥有 Google 帐户的用户添加登录选项到我的网站 我已经能够实现这个 Facebook 但在使用 Google 获取用户帐户信息时遇到问题 我正在使用位于此处的 Google PHP SDK https github com
  • PHP、in_array 和数组中的快速搜索(到最后)

    我对在数组中进行快速搜索的更好方法有疑问 我正在谈论一个特定的情况 假设我有一个数组 L A B C 当我开始时 当程序运行时 L 可能会增长 但到最后 当我进行搜索时 一个可能的原因是 L A B C D E 事实是 当我搜索时 我想要找
  • Yii:使用与控制器布局不同的布局渲染动作

    在 Yii 中 有没有办法使用不同的方式渲染单个动作layout比为控制器定义的值 我有一个操作希望其格式与其他操作不同 并且文档中不清楚这是否可能 我相信您可以调用该操作 layout多变的 public function actionY
  • 我可以使用 vim “star” 搜索来搜索 PHP 类成员和方法吗?

    vim 星号 星号搜索 help star 是一个很棒的功能 它可以让您找到光标所在单词的下一个出现位置 不幸的是 它将美元前缀视为字符串的一部分 因此如果我在类名中的 SearchTerm 上方按 它会在注释中找到 SearchTerm
  • 返回导航缓存 - IE

    当我在 IE 11 上运行 Web 应用程序时 收到如下警告消息 DOM7011 此页面上的代码禁用了后退和前进缓存 为了 更多信息 请参阅 http go microsoft com fwlink LinkID 291337 http g
  • MySQL 查询按父级排序然后子级排序

    我的数据库中有一个页面表 每个页面可以有一个父页面 如下所示 id parent id title 1 0 Home 2 0 Sitemap 3 0 Products 4 3 Product 1 5 3 Product 2 6 4 Prod
  • 在 PHP 上发送不带 SMTP 标头的 SMS

    我正在尝试使用以下对我有用的代码通过 PHP 发送短信验证码 但我越来越 email protected cdn cgi l email protecti
  • C++ 中是否有与 PHP 的explode() 函数等效的函数? [复制]

    这个问题在这里已经有答案了 可能的重复 在 C 中分割字符串 https stackoverflow com questions 236129 splitting a string in c 在 PHP 中 explode 函数将获取一个字
  • PHP Session Id 在页面之间发生变化

    我有一个问题 我在 2 个页面之间丢失了 PHP 会话 session start 包含在一个名为 session inc php 的文件中 该文件包含在每个需要设置会话的页面中 这适用于网站上除一个特定页面 member profile

随机推荐