PHP'deki bir işlevin nereden çağrıldığını öğrenmenin bir yolu var mı? misal:
function epic()
{
fail();
}
function fail()
{
//at this point, how do i know, that epic() has called this function?
}
Yanıtlar:
Kullanabilirsiniz debug_backtrace()
.
Misal:
<?php
function epic( $a, $b )
{
fail( $a . ' ' . $b );
}
function fail( $string )
{
$backtrace = debug_backtrace();
print_r( $backtrace );
}
epic( 'Hello', 'World' );
Çıktı:
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
)
)
)
Kullanım 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()...
}
}
debug_backtrace()
, pahalı bir arama. Çağrı zincirlerini belirlemek için kullanma alışkanlığı edinmeyin. Bu işlevleri "korumak" istiyorsanız, OOP ve korumalı yöntemleri kontrol edin.
Bulduğum en hızlı ve en basit çözüm
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 dizüstü bilgisayarda hızı test ediyorum: Intel Pentiom CPU N3530 2.16GHz, RAM 8GB
global $times;
$start = microtime(true);
$trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1);
$times[] = microtime(true) - $start;
Sonuçlar:
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
Öyleyse, gerçekten nasıl olduğunu hala bilmiyorsanız, işte çözüm:
$backtrace = debug_backtrace();
echo 'Mu name is '.$backtrace[1]['function'].', and I have called him! Muahahah!';
Debug_backtrace işlevini kullanın: http://php.net/manual/en/function.debug-backtrace.php
Aşağıdaki kodu deneyin.
foreach(debug_backtrace() as $t) {
echo $t['file'] . ' line ' . $t['line'] . ' calls ' . $t['function'] . "()<br/>";
}
Yığının en üstünde aramanın tam kaynağını izlemek istiyorsanız, aşağıdaki kodu kullanabilirsiniz:
$call_origin = end(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS));
Bu, zincirleme işlevleri yok sayar ve yalnızca en alakalı çağrı bilgilerini alır (ilgili, neyi başarmaya çalıştığınıza bağlı olarak gevşek bir şekilde kullanılır).
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");
Umarım birine yardımcı olur. Gerçek işlev httpdocs dışında ise, sunucu buna izin vermeyecek şekilde kurulacağından bulunamaz. Sadece bir klasör derinliğinde test edildi, ancak yinelemeli metodoloji teoride çalışmalıdır.
Bu, 0.1 sürümüne benziyor, ancak üzerinde geliştirmeye devam etmeyi düşünmüyorum, bu yüzden birisi güncellerse onu yeniden yayınlamaktan çekinmeyin.
function ff() { grep "function $1" $(find ./ -name "*.php") }
ardından ff fail
veya arayın ff epic
. bkz: github.com/MaerF0x0/VimSetup/blob/master/bashrc#L122
debug_backtrace()
ne kadar mükemmel bir fonksiyon buldum . Bunu kullanacağım!