为啥我会收到“仅应通过引用传递变量”错误?

Posted

技术标签:

【中文标题】为啥我会收到“仅应通过引用传递变量”错误?【英文标题】:Why am I getting "Only variables should be passed by reference" error?为什么我会收到“仅应通过引用传递变量”错误? 【发布时间】:2014-01-13 14:08:15 【问题描述】:

查看此代码:

$last = end($p = explode('/', $someString));  

收到此通知:

只有变量应该通过引用传递

我真的很困惑,因为$p 是一个变量。

【问题讨论】:

你能显示更多代码吗? $someString 是一个数组吗? @demonking:为什么需要更多代码? 对不起,我的错误,从你的代码中删除$p = Only variables should be passed by reference的可能重复 【参考方案1】:

end() 需要一个变量,而不是一个引用。在您的示例中,$p = explode('/', $someString) 不是变量,而是赋值。正如documentation 所说:

这个数组是通过引用传递的,因为它被函数修改了。这意味着您必须传递一个实变量而不是返回数组的函数,因为只有实变量可以通过引用传递。

你应该这样做:

$p = explode('/', $someString);
$last = end($p); 

【讨论】:

我认为很明显我没有传递返回值,而是 $p 这是一个变量...... @thelolcat 这不是很明显。如果我没记错的话,使用返回的值,然后进行赋值。查看我的编辑。 您的编辑有误。 echo $a = $b 将打印2 任何一种方式:OP 期望它与$a = $b; echo $a 的含义相同,而您说它应该意味着echo $b; $a = $b,但两者都是等价的。 (事实上​​,我认为它实际上意味着$a = $b; echo $b——但同样,等价。) @thelolcat 其实我也不明白根本原因。如果您准确地遵循文档,$p = explode('/', $someString) 不是变量。我目前正在研究为什么将引用用作参数而不是变量本身。 @MathieuImbert 在任何情况下,多重赋值返回值,而不是变量,因此 php 还没有办法通过 OP 建议的方法创建引用。【参考方案2】:

函数 end() 需要一个实变量而不是返回数组的函数,但如果你把函数 return 放在双括号内,PHP 不会报告严格的标准通知:

$last = end( ( explode( '/', $someString ) ) );

【讨论】:

这样更好:) 我希望这不是一个错误 虽然我不建议隐藏警告和通知,但这很有趣。它显然和你描述的完全一样,Danijel。这种行为是否记录在 php 手册的某处?我找不到任何参考。 Here 是关于这个话题的一个有趣的讨论,但似乎没有人知道这个行为是一个特性还是一个错误。 @Jirka 据记载,当您使用$b = ($a = 5) 时,第二侧不再是表达式,而是将其设为变量。【参考方案3】:

问题在于您正在对函数进行赋值,而传递给 $last 的值实际上是函数的结果,而不是 $p。而且,explode 返回对变量的引用。

分两行:

$p = explode('/', $someString);
$last = end($p);  

没有理由在 end() 的函数调用中将 $p 赋值给 $p,除非您稍后使用 $p。为了风格清晰,我建议无论如何分两步完成。

【讨论】:

【参考方案4】:

end() 这样的函数会影响变量并改变它们的值,如果它们应该这样做的话,我们都知道,这意味着通过引用传递!但是这种传球需要倾向,不能随便推东西给他们!

在提供Only variables should be passed by reference 时,实际上问题不是那个变量,但是你在尝试end($p = explode('/', $someString)); 时做到了,而是将它传递给函数的那种,因为你不允许在调用@ 时对其进行引用987654325@,您将Expression 作为输入而不是变量。

表达式

PHP 更进一步地使用表达式,就像许多其他方法一样 语言可以。从某种意义上说,PHP 是一种面向表达式的语言 几乎所有的东西都是一种表达。考虑我们的例子 已经处理好了,$a = 5。很容易看出有两个值 这里涉及到整数常量 5 的值,以及 $a 也正在更新为 5。 但事实是 这里涉及一个额外的价值,那就是 任务本身。分配本身评估为分配 值,在这种情况下为 5。实际上,这意味着 $a = 5,无论 它的作用是一个值为 5 的表达式。 因此,写作 像 $b = ($a = 5) 这样的东西就像写 $a = 5; $b = 5; (一种 分号标记语句的结束)。由于分配被解析 按从右到左的顺序,你也可以写成 $b = $a = 5。

该错误只是您的情况的一种严格错误,而不是致命错误!你知道 PHP 是一门严格的编程语言。但是您可以手动禁用它们。这不会改变结果。

关于这个问题的一些例子:

function foo($a)

    return ++$a;
;
$b = 1;
echo foo(&$b);

错误

Fatal error: Call-time pass-by-reference has been removed; If you would like to pass argument by reference, modify the declaration of foo() 自 PHP 5.3.0 起

或者

function foo(&$a)

    return ++$a;
;
echo foo($b = 1); // output: 2

我们以前见过 Strict Standards: Only variables should be passed by reference

【讨论】:

以上是关于为啥我会收到“仅应通过引用传递变量”错误?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我会收到 ORA-06531:对未初始化集合的引用?

为啥我会收到“无效的列名”?消息 207 级别 16 状态 1 第 14 行

为啥我会收到这种错误验证错误?

为啥我会收到此错误

为啥我会收到错误数量的参数错误?

为啥我会收到错误消息?