追踪代码来源(PHP)

5
我正在处理一个客户的服务器,上面运行着疯狂的专有论坛软件(vBulletin),甚至还配有更糟糕的SEO模块(vbseo)。我无法找出这个页面的php代码来自何处!如何将这个URL跟踪回PHP页面:http://www.example.com/forum/members/connie.html。我刚加入了一个基于大量修改过的vBullitin安装和VBSEO插件的项目。这个特定的插件是具有十几个include()的可怕意大利面代码,还有.htaccess重定向和可能的.httpd.conf更改。然后它从数据库中提取字符串,所以我甚至不能使用grep查找代码文件!是否有一种方法可以堆栈跟踪PHP以记录运行产生页面所需的所有代码?我拥有root访问权限,但不应停止或重新启动服务器。一个简单的包含()层次结构的文件列表就足够了。请注意,我无法使用debug_backtrace,因为我不知道我正在寻找的代码在哪里!debug_backtrace函数恰恰与我需要的相反。谢谢。
5个回答

4
听起来您需要使用Xdebug逐步调试。大多数常用的IDE都支持它,例如NetbeansPHPStorm
资源:

在上述两个IDE中,您可以使用CTRL +单击功能/方法,它将带您到定义该功能/方法的文件中的行。您还可以跟踪两个函数和变量的用法。

跟踪代码是 xdebug 的内置功能。下面是来自 Zend 的一个示例:
<?php

  xdebug_start_trace('c:/data/fac.xt');

  print fac(7);

  function fac($x)
  {
    if (0 == $x) return 1;
    return $x * fac($x - 1);
  }

  xdebug_stop_trace();

?>

跟踪文件输出:
TRACE START [2007-10-26 12:18:48]
    0.0068      53384     -> fac() C:\www\fac.php:5
    0.0069      53584       -> fac() C:\www\fac.php:10
    0.0069      53840         -> fac() C:\www\fac.php:10
    0.0070      54096           -> fac() C:\www\fac.php:10
    0.0070      54376             -> fac() C:\www\fac.php:10
    0.0071      54656               -> fac() C:\www\fac.php:10
    0.0072      54936                 -> fac() C:\www\fac.php:10
    0.0072      55216                   -> fac() C:\www\fac.php:10
    0.0073      55392     -> xdebug_stop_trace() C:\www\fac.php:13
    0.0237      55392
TRACE END   [2007-10-26 12:18:48]

谢谢,但我没有使用集成开发环境。代码正在远程服务器上运行,我无法在本地进行镜像。因此,我通过SSH登录并在VIM中进行编辑。 - dotancohen
你可以远程运行xdebug,而且Netbeans是免费的。这里没有任何借口 :) - AlienWebguy
我明白了,谢谢!现在我只需要说服所有者让我安装它。谢谢! - dotancohen
3
在运行中的服务器上安装调试扩展是一个非常糟糕的主意。 - Robin

1

查看debug_backtrace函数 - 即使在生产服务器上也应该始终可用。


OP明确表示debug_backtrace正好是他所不需要的相反情况。 - AlienWebguy
问题在于我不知道代码运行在哪个文件中。这正是我试图弄清楚的! - dotancohen
那么在所有文件中加入调试回溯的调用!在生产服务器上安装调试扩展真的很愚蠢,如果你不被允许重新启动Apache,这也是不可能的。 - Robin

1

你还可以使用apd扩展;这将为每个请求编写一个文件,其中包含了请求期间调用的PHP函数的日志。


仔细一想,似乎这个扩展需要程序员已经知道代码在哪个文件中运行。这正好与我所需的相反。 - dotancohen
1
不一定需要;一旦调用了 apd_set_pprof_trace,扩展程序就会记录每个后续的函数调用。如果您在请求中足够早地进行此调用(例如通过在 .htaccess 文件中使用 auto_prepend_file 指令),则应该能够找出您在代码中的位置。 - Ken Keenan

1

phptrace是一个非常棒且简单易用的追踪PHP代码执行的工具,你可以试试。


0

要追踪特定函数的起源,您可以这样做:

$reflFunc = new ReflectionFunction('function_name');
print $reflFunc->getFileName() . ':' . $reflFunc->getStartLine();

查看如何找到函数定义的位置?

要追踪特定类的起源,可以这样做:

$reflClass = new ReflectionClass('class_name');
print $reflClass->getFileName() . ':' . $reflClass->getStartLine();

要获取制作页面所使用的所有包含文件列表,您可以这样做:

var_dump(get_included_files());

要获取页面上定义的所有函数列表,可以这样做:

var_dump(get_defined_functions());

要获取页面上所有用户定义函数的列表,可以这样做:
$defined_functions = get_defined_functions();
var_dump($defined_functions["user"]);

这个回答并没有回答所提出的问题,而是针对标题的一种可能解释进行了回答。我没有给它点踩,因为它包含有用的信息,但这个问题页面不是它的适当位置。欢迎来到 Stack Overflow! - dotancohen
感谢您没有对此进行负面评价。为了辩护,问题是:“有没有办法堆栈跟踪PHP以记录生成页面的所有代码?……列出用于生成页面的include()文件层次结构的简单列表就足够了。”这个问题的第二部分可以通过get_included_files()来回答。它不返回分层数组,只返回数字数组,但这是我知道的最接近的解决方案。关于“记录[所有代码]”的问题,存在歧义,但我假设它指的是所有函数和方法,这是我回答的另一部分。 - kloddant
此外,OP表示:“debug_backtrace函数正好与我所需的相反。” debug_backtrace函数的相反部分是我的答案的第一部分。 - kloddant
哦,显然你是楼主。那我应该用不同的措辞。 - kloddant

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接