变量变量作为PHP中的函数参数

时间:2020-02-20 16:37:25

标签: php

我一直在玩耍,看看是否可以在PHP中设置一个更动态的方法。

usort($dataset, function($a, $b){ return strcasecmp($a[$this->parameters], $b[$this->parameters]); });

此行将按字母降序对数组元素进行排序。但是,如果我们以$a$b交换变量function($a, $b)($a[$this->parameters], $b[$this->parameters]),则会得到相反的效果(降序)。

当我调查此事时,PHP中有诸如变量变量之类的东西。这样的一个例子是

$a="hello";
$$a="oops";
echo($hello);die;

但是,如果我类似地尝试在上面的代码行中实现这一点,则会出现错误。

$first = 'b';
$second = 'a';
usort($dataset, function($$first, $$second){ return strcasecmp($a[$this->parameters], $b[$this->parameters]); });

错误:Parse error: syntax error, unexpected '$', expecting variable (T_VARIABLE)

这个想法是能够基于iff语句结果反转效果,以重新定义$first$second变量。否则,人们将需要重复几乎相同的代码。

我错过了什么吗?也许有其他方法可以实现这一目标?

2 个答案:

答案 0 :(得分:2)

解析变量的动态名称是在运行时发生的事情,而不是在解释器(即编译)时发生的事情。因此,您不能将其作为您希望能够做的动态参数传递。

鉴于这是不可能的,原因很简单:即使您在编译时设法传递不同的名称,也只能比较一组值。什么会使回调调用不传递a<b,然后传递a>b,然后传递a==b(将它们想象为值)?什么都没有,而且确实会发生。

话虽如此,您可以在传递给最终回调之前尝试验证哪个值较小,但这只会增加一个额外的层,而不是总是以相同的方式进行排序(甚至根本不进行排序):

usort($dataset, function($a, $b)
{ 
    if ($a > $b) {
        return $b <=> $a;
    }
    return $a <=> $b;
});

var_dump($dataset);

// output
array(3) {
  [0]=>
  int(3)
  [1]=>
  int(1)
  [2]=>
  int(7)
}

我完全知道这根本无法解决您的问题。我只是想证明它甚至不会以这种方式工作。

我认为这里的关键事实是您在回调中定义了排序机制,因此您必须确保在该定义中对它进行升序或降序排序,因为这就是它的作用

还有一点,我认为自spaceship operator起,排序回调就很容易在PHP中创建:

// defines: sort ASC
usort($dataset, function($a, $b) { return $a <=> $b; });
// defines: sort DESC
usort($dataset, function($a, $b) { return $b <=> $a; });

PHP 7.4以后的箭头功能更是如此:

// ASC
usort($dataset, fn($a, $b) => $a <=> $b);
// DESC
usort($dataset, fn($a, $b) => $b <=> $a);

总而言之,我完全理解您的来历,但也许您正在尝试解决甚至根本不存在的问题?

答案 1 :(得分:1)

我想对@ArSeN的一个很好的答案进行扩展,以添加更多的计算机科学上下文来说明为什么这根本不是“一件事”。如果您看一下如何在处理器级别(ASM语言)实现函数,您会很快意识到,传递给函数的参数名称甚至没有在二进制程序中使用。实际上,它们只是使您成为程序员的生活而已。大多数调用约定在stack frame上将函数参数实现为函数之间的空间。在函数内部以它们各自的内存偏移量访问它们。大多数C书籍和课程都会详细介绍这个概念,但是用简单的英语来说,这意味着参数的名称无关紧要,因为最终二进制文件仅使用参数的顺序。它在PHP中已经被抽象得很远,但是,它仍然非常相关,如果您打算以专业水平进行编程,则应该了解一些东西。