Есть ли способ узнать, откуда была вызвана функция в PHP? Пример:
function epic()
{
fail();
}
function fail()
{
//at this point, how do i know, that epic() has called this function?
}
Есть ли способ узнать, откуда была вызвана функция в PHP? Пример:
function epic()
{
fail();
}
function fail()
{
//at this point, how do i know, that epic() has called this function?
}
Вы можете использовать debug_backtrace()
.
Пример:
<?php
function epic( $a, $b )
{
fail( $a . ' ' . $b );
}
function fail( $string )
{
$backtrace = debug_backtrace();
print_r( $backtrace );
}
epic( 'Hello', 'World' );
Вывод:
Array
(
[0] => Array
(
[file] => /Users/romac/Desktop/test.php
[line] => 5
[function] => fail
[args] => Array
(
[0] => Hello World
)
)
[1] => Array
(
[file] => /Users/romac/Desktop/test.php
[line] => 15
[function] => epic
[args] => Array
(
[0] => Hello
[1] => World
)
)
)
Используйте debug_backtrace()
:
function fail()
{
$backtrace = debug_backtrace();
// Here, $backtrace[0] points to fail(), so we'll look in $backtrace[1] instead
if (isset($backtrace[1]['function']) && $backtrace[1]['function'] == 'epic')
{
// Called by epic()...
}
}
Итак, если вы все еще ДЕЙСТВИТЕЛЬНО не знаете, как это сделать, то вот решение:
$backtrace = debug_backtrace();
echo 'Mu name is '.$backtrace[1]['function'].', and I have called him! Muahahah!';
Самое быстрое и простое решение, которое я нашел
public function func() { //function whose call file you want to find
$trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1);
}
$trace: Array
(
[0] => Array
(
[file] => C:\wamp\www\index.php
[line] => 56
[function] => func
[class] => (func Class namespace)
[type] => ->
)
)
Я тестирую скорость на ноутбуке Lenovo: процессор Intel Pentiom N3530 2,16 ГГц, оперативная память 8 ГБ
global $times;
$start = microtime(true);
$trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1);
$times[] = microtime(true) - $start;
Результаты:
count($times): 97
min: 2.6941299438477E-5
max: 10.68115234375E-5
avg: 3.3095939872191E-5
median: 3.0517578125E-5
sum: 321.03061676025E-5
the same results with notation without E-5
count($times): 97
min: 0.000026941299438477
max: 0.0001068115234375
avg: 0.000033095939872191
median: 0.000030517578125
sum: 0.0032103061676025
Используйте функцию debug_backtrace: http://php.net/manual/en/function.debug-backtrace.php
Попробуйте ввести код.
foreach(debug_backtrace() as $t) {
echo $t['file'] . ' line ' . $t['line'] . ' calls ' . $t['function'] . "()<br/>";
}
function findFunction($function, $inputDirectory=""){
//version 0.1
$docRoot = getenv("DOCUMENT_ROOT");
$folderArray = null;
$dirArray = null;
// open directory
$directory = opendir($docRoot.$inputDirectory);
// get each entry
while($entryName = readdir($directory)) {
if(is_dir($entryName) && $entryName != "." && $entryName != ".."){
$folderArray[] = str_replace($inputDirectory, "", $entryName);
}
$ext = explode(".", $entryName);
if(!empty($ext[1])){
$dirArray[] = $docRoot.$inputDirectory."/".$entryName;
}
}
// close directory
closedir($directory);
$found = false;
if(is_array($dirArray)){
foreach($dirArray as $current){
$myFile = file_get_contents($current);
$myFile = str_replace("<?php", "", $myFile);
$myFile = str_replace("?>", "", $myFile);
if(preg_match("/function ".$function."/", $myFile)){
$found = true;
$foundLocation = $current;
break;
}
}
}
if($found){
echo $foundLocation;
exit;
} else if(is_array($folderArray)){
foreach($folderArray as $folder){
if(!isset($return)){
$return = findFunction($function, $inputDirectory."/".$folder);
} else if($return == false){
$return = findFunction($function, $inputDirectory."/".$folder);
}
}
} else {
return false;
}
}
findFunction("testFunction", "rootDirectory");
Надеюсь, это поможет кому-то. Если фактическая функция находится за пределами httpdocs, она не может быть найдена, потому что сервер будет настроен так, чтобы не разрешать ее. Тестировал только одну папку, но рекурсивная методология должна работать теоретически.
Это похоже на версию 0.1, но я не намерен продолжать его разработку, поэтому, если кто-то обновляет его, он может перепроверить его.