5

I'm going through a customer's server, running crazy proprietary forum software (vBulletin) and even worse SEO mods (vbseo). I cannot figure out where the php code for a page is coming from! How to trace this URL back to a PHP page: http://www.example.com/forum/members/connie.html I just joined a project with the code based on a heavily modified vBullitin install with the VBSEO plugin. This particular plugin is horrific spaghetti code with tens of include()s, .htaccess redirects and possibly .httpd.conf changes. Then it pulls strings from a database so I cannot even use grep to find the code file!

Is there any way to stack-trace PHP to log all the code that runs to produce a page? I have root access but I am not supposed to stop or restart the server. A simple list of the include() hierarchy of files that went into producing the page would suffice.

Note that I cannot use debug_backtrace because I don't know where the code I'm looking for is! The debug_backtrace function is the exact opposite of what I need.

Thanks.

dotancohen
  • 30,064
  • 36
  • 138
  • 197

5 Answers5

4

Sounds like you need to step through it with Xdebug. Most common IDE's support it such as Netbeans and PHPStorm.

Resources:

In both the above mentioned IDE's, you can CTRL+Click a function/method and it will take you to the line in the file where it is defined. You can also track usages for both functions and variables.

Tracing code is built-in to xdebug. Here's an example from 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 file output:

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]
AlienWebguy
  • 76,997
  • 17
  • 122
  • 145
1

phptrace is an awesome and simple tool to trace php code executions, you can have a try.

renenglish
  • 728
  • 1
  • 9
  • 18
1

Check out the debug_backtrace function - this should always be available, even on production servers.

Robin
  • 4,242
  • 1
  • 20
  • 20
  • OP Specifically said debug_backtrace is the exact opposite of what he needs. – AlienWebguy Aug 28 '11 at 16:44
  • The problem is that I do not know in which file the code is running. That is exactly what I am trying to figure out! – dotancohen Aug 28 '11 at 17:47
  • Well then put a call to debug backtrace in all of the files! Installing debug extensions on a live server is really dumb, and impossible if you're not allowed to restart Apache. – Robin Aug 29 '11 at 11:21
1

You can also use the apd extension; this will write a file for each request containing a log of what PHP functions were called during the request.

Ken Keenan
  • 9,818
  • 5
  • 32
  • 49
  • On second though, it looks as if this extension requires the programmer to already know in which file the code is running. That is the exact opposite of what I need. – dotancohen Sep 01 '11 at 20:29
  • 1
    Not necessarily; once you call `apd_set_pprof_trace`, every subsequent function call is logged by the extension. If you make this call sufficiently early in the request (e.g., by using an `auto_prepend_file` directive in your `.htaccess` file), you should be able to find out where you're ending up in the code – Ken Keenan Sep 03 '11 at 10:43
0

To trace the origin of a specific function, you can do this:

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

See How to find out where a function is defined?

To trace the origin of a specific class, you can do this:

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

To get a list of all the includes that went into making a page, you can do this:

var_dump(get_included_files());

To get a list of all the functions that are defined on a page, you can do this:

var_dump(get_defined_functions());

To get a list of all the user-defined functions on a page, you can do this:

$defined_functions = get_defined_functions();
var_dump($defined_functions["user"]);
Community
  • 1
  • 1
kloddant
  • 1,026
  • 12
  • 19
  • This answer does not address the question being asked, but rather addresses one possible interpretation of the title. I've not downvoted as it contains useful information, but this question page is not the place for it. Welcome to Stack Overflow! – dotancohen May 05 '16 at 11:14
  • I thank you for not downvoting. In my defense, the question was: "Is there any way to stack-trace PHP to log all the code that runs to produce a page? ... A simple list of the include() hierarchy of files that went into producing the page would suffice." The second part of this question is answered by get_included_files(). This does not return hierarchical array, just a numerical array, but that is the closest solution I know of. The first part of the question, about "log[ging] all the code," is ambiguous, but I assumed it meant all functions and methods, the other part of my answer. – kloddant May 05 '16 at 13:04
  • Also, the OP said that, "The debug_backtrace function is the exact opposite of what I need." The opposite of the debug_backtrace function is the first part of my answer. – kloddant May 05 '16 at 13:05
  • Oh, apparently you are the OP. I should have phrased that differently then. – kloddant May 05 '16 at 13:17