Can an included PHP file know where it was included from?
For example,
This is index.php
<?
require_once('header.php');
?>
Can header.php know it was included by index.php?
--EDIT--
I found开发者_Go百科 a solution:
function backtrace_filename_includes($name){
$backtrace_array=debug_backtrace();
if (strpos($backtrace_array[1]['file'],$name)==false){
return false;
}else{
return true;
}
}
header.php
<?
if (backtrace_filename_includes('index.php')) echo "index.php";
?>
While $_SERVER['PHP_SELF']
will contain the currently executing script, there is no way to determine from an included file which specific script caused the include.
This means that if a.php
includes b.php
, which includes c.php
, c.php
will have no way of knowing that b.php
was the includer. The best you can get is that a.php
is the currently executing script.
Edit: Yup, my above answer is technically wrong -- you can use debug_backtrace
to find the caller, even without functions, up until PHP 5.4, which removes this functionality.
a.php:
<?php
echo 'A';
include 'b.php';
b.php:
<?php
echo 'B';
include 'c.php';
c.php:
<?php
echo 'C';
print_r(debug_backtrace());
Output:
ABCArray
(
[0] => Array
(
[file] => /tmp/b.php
[line] => 3
[function] => include
)
[1] => Array
(
[file] => /tmp/a.php
[line] => 3
[args] => Array
(
[0] => /tmp/b.php
)
[function] => include
)
)
So while this works, you probably shouldn't use it. debug_backtrace
can be a noticeable performance drag when used excessively.
get_included_files()
provides a stack of the files included, in the order they are included, which in my case gave me everything I needed.
Specifically, if you call get_included_files()
within a file that has been included, that file's own file-path will be the most recent entry on the stack returned by get_included_files()
, the one that included it is above that, etc.
The caveat is that files are only listed once, so if the same file is included more than once, only the first include will show up in the stack. For my purposes that wasn't an issue, but it definitely means this won't work in all cases.
Specific example: imagine the file 'test1.php' includes 'test_include.php'. The result of get_included_files() from the perspective of 'test_include.php' after loading test1.php in the browser are as follows (given, as you can see, that I've got an auto_prepend file, which in turn loads an autoloader).
array(4) {
[0]=>
string(21) "/www/auto_prepend.php"
[1]=>
string(19) "/www/autoloader.php"
[2]=>
string(14) "/www/test1.php"
[3]=>
string(21) "/www/test_include.php"
}
So test_include.php only has to do a little array_pop'ing to figure out who included it.
$_SERVER['PHP_SELF']
should still point to file originally accessed, or you could set a variable before the require, eg:
$section = 'home';
require_once('header.php');
...
if ($section == 'home') {
...
}
debug_print_backtrace();
Check PHP docu
PHP tracks the file that does the including for you in the backtrace. With a little helper function you can get the filename that had the last include command:
/**
* get filename that included this file
*
* @return string filename
*/
function include_by() {
$bt = debug_backtrace(0);
while ($b = array_shift($bt)) {
if (in_array($b['function'], array('require', 'require_once', 'include', 'include_once'), 1)) {
return $b['file'];
}
}
throw new BadFunctionCallException('Not an include.');
}
Usage:
main.php:
<?php
include('sub.php');
sub.php:
<?php
echo basename(include_by()); # main.php
See as well a related usage of the backtrace: Caller function in PHP 5?.
Easiest way in the web server environment: $_SERVER['SCRIPT_FILENAME']
will show the original file that is called.
Universal way - debug_backtrace()
will show you all previous steps of the execution, which will include calls to require/include functions.
精彩评论