1 SelectLanguages 2023-04-27 08:00:23 +08:00 ???? $user='xxx'; function test($str){ if($str){ }else{ var_dump($user); } } test($user); |
![]() | 2 Xusually 2023-04-27 08:05:01 +08:00 via iPhone 最方便的办法是使用反射 ReflectionFunction 。 当然你还可以使用 get_defined_vars()去查找。 能问下你的场景吗,很少有人需要这么做,在做日志工具? |
![]() | 3 buxudashi OP @Xusually 就是简单的保存下调用者的变量名。这样报错时,直接全局查找这个名就知道哪里错了。test 其实是个全局的异常用。 |
4 awinds 2023-04-27 08:39:18 +08:00 报错堆栈信息不是有行号吗? |
![]() | 6 chancefyi 2023-04-27 08:42:48 +08:00 func_get_args() |
![]() | 8 user20190708 2023-04-27 09:09:11 +08:00 via iPhone 据我所知是拿不到 |
![]() | 9 zlhsvc 2023-04-27 09:12:59 +08:00 异常可以自动捕获写入日志的啊,日志打印堆栈信息不就好了,你这操作有点看不明白 |
![]() | 10 suyuyu 2023-04-27 09:13:33 +08:00 能拿到的。以前我也搞过记不清了你试试是不是 debug_backtrace |
11 1343EFF 2023-04-27 09:14:01 +08:00 直接上 try |
![]() | 12 8355 2023-04-27 09:15:09 +08:00 传入之后就是值拷贝了 咋能取到呢。。。 |
13 QlanQ 2023-04-27 09:17:49 +08:00 调用者给的变量名都是不一样的? 异常的捕获和报错不冲突呀 |
![]() | 14 encro 2023-04-27 09:18:16 +08:00 正确的方法: 直接抛出异常,在外层捕获异常,然后就能获得异常的 trace 。 |
![]() | 17 encro 2023-04-27 09:23:20 +08:00 取不到。。。 |
![]() | 18 zjsxwc 2023-04-27 09:23:26 +08:00 https://gist.github.com/zjsxwc/970216c64d7cc5905e86a0d17f62bbb2 我刚刚用 debug_backtrace 写了个 php 取到调用时实参位置的内容。 |
19 Rache1 2023-04-27 09:31:12 +08:00 |
![]() | 20 user20190708 2023-04-27 09:31:59 +08:00 via iPhone 看 $GLOBALS 有这个名字,研究下咋取出来? |
21 angryPHP 2023-04-27 09:32:34 +08:00 为什么会有这种需求 |
22 Rache1 2023-04-27 09:38:09 +08:00 @Rache1 这个很简陋,实际上最好还要根据 debug_backtrace 提供的行号、位置信息与 php-parser 解析出来的行号位置进行比较一下,按照例子里面的,如果同一个函数在一个文件里面调用了多次,就只有第一次会被获取到了。而且这个只是简单的对函数调用进行了处理,对于方法调用没有处理。 这里仅仅是提供一个思路 |
![]() | 23 user20190708 2023-04-27 09:40:38 +08:00 <?php $i = 1; function a($b) { $g = $GLOBALS; $v = array_keys($g); print_r(end($v)); } a($i); |
24 Twislight 2023-04-27 09:42:39 +08:00 传两个参数,另一个是参数名 |
![]() | 25 asmoker 2023-04-27 09:55:32 +08:00 via Android 加 sentry |
![]() | 27 akagishigeru 2023-04-27 10:28:24 +08:00 `sf `上有人提过,可以试试 ```php function test($str){ $trace = debug_backtrace(); $vLine = file( __FILE__ ); $fLine = $vLine[ $trace[0]['line'] - 1 ]; preg_match( "#\\$(\w+)#", $fLine, $match ); print_r( $match ); } ``` |
28 brader 2023-04-27 10:39:05 +08:00 楼主你好,我给你实现了,代码如下: ``` <?php function test($str) { var_dump($str); // 调用此函数堆栈 $stack = xdebug_get_function_stack(); $lastStack = array_pop($stack); // print_r($lastStack); $lineStr = getLine($lastStack['file'], $lastStack['line']); // print_r($lineStr); // 正则提取参数 preg_match('#test\s*\((?P<params>.*)\)\s*;#', $lineStr, $matches); // 格式化参数 $params = explode(',', $matches['params']); $params = array_map('trim', $params); print_r($params); } $user = 'xxx'; test($user); /** * 读取文件指定行内容 * @param $file * @param $line * @param int $length * @return false|string|null */ function getLine($file, $line, $length = 4096) { $returnTxt = null; // 初始化返回 $i = 1; // 行数 $handle = @fopen($file, "r"); if ($handle) { while (!feof($handle)) { $buffer = fgets($handle, $length); if ($line == $i) { $returnTxt = $buffer; break; } $i++; } fclose($handle); } return $returnTxt; } ``` |
29 brader 2023-04-27 10:44:28 +08:00 抱歉,刚才的正则里面,函数名忘记写变量了,换为这个: ``` preg_match("#{$lastStack['function']}\s*\((?P<params>.*)\)\s*;#", $lineStr, $matches); ``` |
![]() | 30 lisxour 2023-04-27 11:36:21 +08:00 你这一通乱搞还不如上分析工具和做好日志 |
![]() | 31 buxudashi OP 看来都得根据文件所在行的行号才能取到了。 |
![]() | 32 buxudashi OP 没更好的办法就散了。 |
![]() | 33 heysnakelis 2023-05-12 18:02:26 +08:00 public static function get_variable_name($var, $scope) { $name = array_search($var, $scope, true); // 根据值查找变量名称 return $name; } public static function printVar($var, $scope) { $name = self::get_variable_name($var, $scope); print_r([$name => $var]); } |
![]() | 34 heysnakelis 2023-05-12 18:03:23 +08:00 Tool::printVar($get_params_1, get_defined_vars()); class Tool { public static function get_variable_name($var, $scope) { $name = array_search($var, $scope, true); // 根据值查找变量名称 return $name; } public static function printVar($var, $scope) { $name = self::get_variable_name($var, $scope); print_r([$name => $var]); } } |
![]() | 35 buxudashi OP @heysnakelis 这个相当于传参时就传上去了。两个变量值相同时,这个查找是不对的。 |
36 wxfjamdc 2023-07-01 14:14:23 +08:00 function foo($a, $b, $c) { $ref = new ReflectionFunction(__FUNCTION__); $params = $ref->getParameters(); foreach ($params as $param) { echo $param->getName() . "\n"; } } foo(1, 2, 3); |
38 wxfjamdc 2023-07-03 10:23:38 +08:00 function foo($a, $b, $c) { $trace = debug_backtrace(); $args = $trace[0]['args']; print_r($args); } $actualArgument = 1; foo($actualArgument, 2, 3); 只能在 PHP 8.0 或更高版本中使用,因为在之前的版本中,debug_backtrace()函数返回的数组中的 args 元素是实参的值,而不是名称。另外,这种方法也只能在实参是变量的情况下使用,如果实参是常量或表达式,那么返回的名称将是它们的值。 |