Previously while talking about inclusion checks I had included a few helpful digraphs of php includes. Those were drawn with the help of a gdb macro and a bit of sed/awk. But that becomes a real hassle to actually use very quickly while inspecting fairly large php applications.
The solution to repeatable include graphs from php came from the way the include_once override hack was implemented. By overriding the INCLUDE_OR_EVAL opcode in Zend, I could insert something which could potentially log all the various calls being made to it.
That is exactly what inclued does. The extension provides a single function which provides a copy of the collected data, aptly named inclued_get_data().
<?php include("x.php"); print_r(inclued_get_data());
The above peice of code returns an array with too much information.
Array ( [includes] => Array ( [0] => Array ( [operation] => include [op_type] => 2 [filename] => x.php [opened_path] => /tmp/x.php [fromfile] => /tmp/z.php [fromline] => 2 ) ) )
Overriding the opcode implies that more information can be collected, like whether the include parameter was a constant (i.e APC can optimize it to a full path), the function the include was in (__autoload *cough*) and the stream wrapper (phar: for instance). The information also includes info about whether the include_once was ignored because of duplication.
Only Data: The extension however does not make any judgements on the code. I have resisted the temptation to put an error log saying "If eval() is the answer, you're almost certainly asking the wrong question" . But there are interesting ways to massage this data into something useful. For example, I just put the following lines into the Wordpress index.php.
$fp = fopen("/tmp/wp.json", "w"); fwrite($fp, json_encode(inclued_get_data());
Loading the JSON data and pushing out a graphviz layout was almost too easy. Here's a clipped section of how my graph ended up looking.
The graph shows about 40-odd includes being hit for a single request, but isn't messy at all. Hopefully, someone finds an actual peice of sphagetti includes which shows off the beauty of this ext (remember, this shows include_once misses & hits).
Hope this helps people debug "Where is this include coming from ?" question I've run into so many times :)
--It was the kind of mental picture you tried to forget. Unsuccessfully.
-- Terry Pratchett, "The Light Fantastic"