【问题标题】:Modify multiple variables with single function in PHP在 PHP 中使用单个函数修改多个变量
【发布时间】:2016-04-13 20:59:09
【问题描述】:

我需要以同样的方式修改一些变量。例如,当某些条件满足时,我需要将每个变量乘以 2。像这样:

$a = 10;
$b = 100;
$c = 1000;
$d = 10000;

if($someCondition) {
    $a *= 2;
    $b *= 2;
    $c *= 2;
    $d *= 2;
}

这里我想调用一个函数将更改应用到所有变量,而不是一一相乘。我尝试使用这样的回调函数(为这种类型的简单计算编写这样的函数可能看起来很傻,但我有更复杂的事情要做,这里保持简单以便更好地理解)

试用 1

function multiply_vars(&$a,&$b,&$c,&$d) {
    foreach(func_get_args() as $val) {        
        $val *= 2;
    }
}

if($someCondition) {
    multiply_vars($a,$b,$c,$d);
}

这可行,但我需要确切知道我传递给函数的变量数量,并将每个变量设置为& 的引用。例如,当我传递 5 个变量进行修改时,上面的函数会给我错误的结果。

试用 2

function multiply_vars() {
    foreach(func_get_args() as $varname) {
        global $$varname;
        $$varname *= 2;
    }
}

if($someCondition) {
    modify_vars('a','b','c','d');
}

这适用于全球范围内。但问题是,我在一个类函数中执行此操作,其中global $$varname 指的是我的类函数之外的一个变量。

还有其他方法可以实现我的目的吗?

注意:我不想将变量放入数组中。我知道,如果在数组中,可以通过array_map() 函数更好地解决。

【问题讨论】:

  • 为什么不直接把它们作为数组传入,返回数组,返回时再解析呢?
  • @JeremyJackson,我需要修改原始变量。您能否更好地将您的建议发布为带有代码的答案,以便我更好地了解它将如何实现我的目的?
  • 照JJ说的做,用数组。将其作为参数发送,并让一些函数/方法完成工作,并返回可以更新全局范围的结果。

标签: php variables


【解决方案1】:

您想要一个可变参数列表
下面是通过引用将可变数量的参数传递给函数的示例:
PHP: variable-length argument list by reference?

从以上链接复制粘贴:

示例 1:

function foo(&...$args) {
    $args[0] = 'bar';
}
foo($a);
echo $a, "\n";
#  output:
#a

示例 2:

function number(&...$args) {
    foreach ($args as $k => &$v) {
        $v = $k;
    }
}
number($zero, $one, $two);
echo "$zero, $one, $two\n";
#  output:
#0, 1, 2

【讨论】:

  • C 有可变参数列表,我不知道 PHP 是否有。啊,确实如此:secure.php.net/manual/en/…
  • 这是一个通过引用传递的可变参数列表的示例。我认为这正是您想要的:stackoverflow.com/questions/1925253/…
  • 感谢您的发现。你能用一些代码改进你的答案吗,我想投票。
  • 需要注意的是,它在$v$v 之前没有& 对我有用
【解决方案2】:

我意识到您说过您不想将变量放入数组中。但是,您可能会传递一个引用数组以避免额外的值复制。例如

<?php
$a = 10;
$b = 100;
$c = 1000;
$d = 10000;

function multiply_vars($args) {
    foreach($args as &$arg) $arg *= 2;
}

multiply_vars([&$a, &$b, &$c, &$d]);

但是,如果您使用的是 PHP 5.6,我认为 Magical Gordon 的更新答案是更好的解决方案。

【讨论】:

  • 我重新进行了仔细检查,在 PHP 5.6.12 上它对我有用。错误在哪一行?
  • 对不起,错误是其他原因,我再检查一遍。
  • 是的,这确实有效。当我尝试使用&amp; 传递变量时,我遇到了一些错误Call-time pass-by-reference has been removed;。但是您将它们放入数组中的技巧非常完美。但正如你所提到的,我正在检查 Magical 的答案,我只是在寻找类似的东西。还是谢谢。
【解决方案3】:

在这里扩展其他答案,为什么不使用对象?我假设您的问题是一个简单的案例,但有一些好处:对象总是通过引用传递,并且分配给对象属性的值本身可以通过引用访问。

例如:

$numbers = new \StdClass();
$numbers->a = 10;
$numbers->b = 100;
$numbers->c = 100;
$numbers->d = 100;

然后您将在全局范围内使用 $numbers-&gt;a 而不是 $a - 或通过引用 $a = &amp;$numbers-&gt;a; 使用另一个变量

function multiply(StdClass $numbers, $multiple = 2)
{
    // Iteration isn't directly achievable with StdClass but...
    foreach (get_object_vars($numbers) as $key => $value) {
        $numbers->$key *= $multiple;
    }
}

最后,我们的条件:

if (true === myCondition) {
    multiply($numbers);
}

【讨论】:

  • 请检查我在问题底部的注释,我想使用我的原始变量,而不是数组或对象。否则,我会简单地用数组解决我的问题并使用array_map() 函数进行修改。 (还要注意,我会根据不同的条件修改不同的变量。)
  • 那么请看Magical Gordon的回答;通过引用传递参数的可变参数函数定义将支持任意数量的参数,并允许将值返回到调用范围。
【解决方案4】:

您的需求表明您的策略不正确。即使它有效,您的代码可读性和可维护性也不会很好! 无论如何,我建议您创建一个函数而不是您的过程,您可以在需要时调用它并将原始变量替换为输出。

一个例子:

Function doStuff ($input){
    treat_input;
    Return output;
 }

$x = doStuff ($×);
 ....

好吧,我知道你需要调用这个函数的次数与你拥有的变量数一样多。但请相信我,根据长期维护脚本的经验,这是您必须采用的方法。

【讨论】:

  • 对不起,我不清楚/确定你在说什么!
【解决方案5】:

我只是将它们作为数组传递。例如:

$variables = array(
    'a' => 10,
    'b' => 100,
    'c' => 100,
    'd' => 1000,
);

function multiply_vars($variables) {
    $returnValues = array();
    foreach($variables as $key => $value) {        
        $newValue = $value * 2;
        array_push($returnValues, array($key => $newValue));
    }
    return $returnValues;
}

if($someCondition) {
    $variablesWithNewValues = multiply_vars($variables);
    //do stuff with  $variablesWithNewValues
}

【讨论】:

  • 我现在明白了,你在说什么。但我想保留我的原始变量,而不是将它们放入数组中。如果它是一个数组,我可以使用array_map() 函数更好地解决我的目的而不是这样做。
  • 你是否一直都知道条件会影响哪些变量?
  • 不同情况可能会有所不同。这就是我将变量传递给函数的原因,
  • 因此,根据满足的条件,您可以将满足某些条件的每个值推送到一个新数组中以传递给函数,当您取回它时,循环遍历每个值并设置它们各自变量。实际上,您也可以在该函数中执行此操作。
  • 不确定,我很清楚你,但你正走向我的试炼 2
猜你喜欢
  • 2020-07-17
  • 1970-01-01
  • 2022-12-07
  • 1970-01-01
  • 1970-01-01
  • 2017-01-06
  • 1970-01-01
  • 2014-06-18
  • 1970-01-01
相关资源
最近更新 更多