Intereting Posts

Может ли встроенный PHP-файл узнать, откуда он был включен?

Например,

Это index.php

<? require_once('header.php'); ?> 

Может ли header.php знать, что он был включен index.php?

–РЕДАКТИРОВАТЬ–

Я нашел решение:

 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"; ?> 

В то время как $_SERVER['PHP_SELF'] будет содержать $_SERVER['PHP_SELF'] исполняемый скрипт, нет способа определить из включенного файла, который вызвал специальный сценарий для include.

Это означает, что если a.php включает b.php , который включает c.php , c.php будет знать, что b.php является включенным. Лучшее, что вы можете получить, это то, что a.php является исполняемым скриптом.


Edit: Yup, мой вышеприведенный ответ технически неверен – вы можете использовать debug_backtrace чтобы найти вызывающего, даже без функций, вплоть до PHP 5.4, который удаляет эту функциональность .

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()); 

Вывод:

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

Поэтому, пока это работает, вы, вероятно, не должны его использовать. debug_backtrace может быть заметным перетаскиванием производительности при чрезмерном использовании.

get_included_files() предоставляет стек включенных файлов в том порядке, в котором они включены, что в моем случае дало мне все, что мне было нужно.

В частности, если вы вызываете get_included_files() в файле, который был включен, собственный путь к файлу этого файла будет самой последней записью в стеке, возвращаемой get_included_files() , тот, который включил его, находится выше этого и т. Д.

Предостережение состоит в том, что файлы перечисляются только один раз, поэтому, если один и тот же файл включен более одного раза, в стеке будут отображаться только первые включенные. Для моих целей это не было проблемой, но это определенно означает, что это не будет работать во всех случаях.

Конкретный пример: представьте, что файл «test1.php» включает в себя «test_include.php». Результат get_included_files () с точки зрения «test_include.php» после загрузки test1.php в браузере выглядит следующим образом (учитывая, что, как видите, у меня есть файл auto_prepend, который, в свою очередь, загружает автозагрузчик) ,

 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" } 

Таким образом, test_include.php должен сделать немного array_pop'ing, чтобы выяснить, кто его включил.

$_SERVER['PHP_SELF'] должен по-прежнему указывать на исходный доступ к файлу или вы можете установить переменную перед требованием, например:

 $section = 'home'; require_once('header.php'); 

 if ($section == 'home') { ... } 

PHP отслеживает файл, который делает включение для вас в backtrace. С помощью небольшой вспомогательной функции вы можете получить имя файла, в котором была последняя команда include:

 /** * 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.'); } 

Применение:

main.php:

 <?php include('sub.php'); 

sub.php:

 <?php echo basename(include_by()); # main.php 

См. Также связанное использование функции backtrace: Caller в PHP 5? ,

 debug_print_backtrace(); 

Проверка документа PHP

Самый простой способ в среде веб-сервера: $_SERVER['SCRIPT_FILENAME'] покажет исходный файл, который вызывается.

Универсальный способ – debug_backtrace() покажет вам все предыдущие шаги выполнения, которые будут включать вызовы функций require / include.