PHP 有没简单办法取到实参的名称?

2023-04-27 07:55:05 +08:00
 buxudashi
如题:
function test($str){
var_dump($str);
}
$user='xxx';
test($user);

怎么能在 test 函数内,取到'user'这个字符串。它是实参的名称。
2342 次点击
所在节点    PHP
39 条回复
angryPHP
2023-04-27 09:32:34 +08:00
为什么会有这种需求
Rache1
2023-04-27 09:38:09 +08:00
@Rache1 这个很简陋,实际上最好还要根据 debug_backtrace 提供的行号、位置信息与 php-parser 解析出来的行号位置进行比较一下,按照例子里面的,如果同一个函数在一个文件里面调用了多次,就只有第一次会被获取到了。而且这个只是简单的对函数调用进行了处理,对于方法调用没有处理。

这里仅仅是提供一个思路
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);
Twislight
2023-04-27 09:42:39 +08:00
传两个参数,另一个是参数名
asmoker
2023-04-27 09:55:32 +08:00
加 sentry
8355
2023-04-27 09:56:57 +08:00
@asmoker #25 推荐楼主看看 方向错了就全错了 用这个 终于出现了
@buxudashi #5
JaguarJack
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 );
}
```
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;
}
```
brader
2023-04-27 10:44:28 +08:00
抱歉,刚才的正则里面,函数名忘记写变量了,换为这个:
```
preg_match("#{$lastStack['function']}\s*\((?P<params>.*)\)\s*;#", $lineStr, $matches);
```
lisxour
2023-04-27 11:36:21 +08:00
你这一通乱搞还不如上分析工具和做好日志
buxudashi
2023-04-27 12:48:23 +08:00
看来都得根据文件所在行的行号才能取到了。
buxudashi
2023-04-27 22:59:02 +08:00
没更好的办法就散了。
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]);
}
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]);
}


}
buxudashi
2023-05-12 18:33:00 +08:00
@heysnakelis 这个相当于传参时就传上去了。两个变量值相同时,这个查找是不对的。
wxfjamdc
318 天前
function foo($a, $b, $c) {
$ref = new ReflectionFunction(__FUNCTION__);
$params = $ref->getParameters();
foreach ($params as $param) {
echo $param->getName() . "\n";
}
}

foo(1, 2, 3);
buxudashi
318 天前
@wxfjamdc
不符合要求的。
$a=5;
foo($a), 我要得到 'a'这个字符串
wxfjamdc
316 天前
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 元素是实参的值,而不是名称。另外,这种方法也只能在实参是变量的情况下使用,如果实参是常量或表达式,那么返回的名称将是它们的值。
wxfjamdc
316 天前
@wxfjamdc Ai 返回的,似乎也不行

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/935791

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX