Câu trả lời:
Bạn có thể sử dụng debug_backtrace()
.
Thí dụ:
<?php
function epic( $a, $b )
{
fail( $a . ' ' . $b );
}
function fail( $string )
{
$backtrace = debug_backtrace();
print_r( $backtrace );
}
epic( 'Hello', 'World' );
Đầu ra:
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
)
)
)
Sử dụng 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()
là một cuộc gọi đắt tiền. Đừng có thói quen sử dụng nó để xác định chuỗi cuộc gọi. Nếu bạn muốn "bảo vệ" các chức năng đó, hãy xem OOP và các phương pháp được bảo vệ.
Giải pháp nhanh nhất và đơn giản nhất như tôi đã tìm thấy
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] => ->
)
)
Mình test tốc độ trên laptop Lenovo: CPU Intel Pentiom N3530 2.16GHz, RAM 8GB
global $times;
$start = microtime(true);
$trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1);
$times[] = microtime(true) - $start;
Các kết quả:
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
Vì vậy, nếu bạn vẫn THỰC SỰ không biết làm thế nào, thì đây là giải pháp:
$backtrace = debug_backtrace();
echo 'Mu name is '.$backtrace[1]['function'].', and I have called him! Muahahah!';
Sử dụng hàm debug_backtrace: http://php.net/manual/en/ Chức năng.debug-backtrace.php
Hãy thử mã bên dưới.
foreach(debug_backtrace() as $t) {
echo $t['file'] . ' line ' . $t['line'] . ' calls ' . $t['function'] . "()<br/>";
}
Nếu bạn muốn theo dõi nguồn gốc chính xác của cuộc gọi ở đầu ngăn xếp, bạn có thể sử dụng mã sau:
$call_origin = end(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS));
Điều này sẽ bỏ qua các chức năng được xâu chuỗi và chỉ nhận được thông tin cuộc gọi phù hợp nhất (có liên quan được sử dụng một cách lỏng lẻo vì nó phụ thuộc vào những gì bạn đang cố gắng hoàn thành).
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");
Hy vọng nó sẽ giúp ai đó. Nếu chức năng thực sự nằm ngoài httpdocs thì không thể tìm thấy nó vì máy chủ sẽ được thiết lập để không cho phép nó. Chỉ kiểm tra nó sâu một thư mục nhưng phương pháp đệ quy sẽ hoạt động trên lý thuyết.
Đây giống như phiên bản 0.1 nhưng tôi không có ý định tiếp tục phát triển nó nên nếu ai đó cập nhật, hãy đăng lại nó.
function ff() { grep "function $1" $(find ./ -name "*.php") }
rồi gọi ff fail
hoặc ff epic
. xem: github.com/MaerF0x0/VimSetup/blob/master/bashrc#L122
debug_backtrace()
một chức năng tuyệt vời. Tôi sẽ sử dụng cái này!