while循环:只有变量可以通过引用错误传递

时间:2016-04-08 13:11:47

标签: php

我遇到了一个"只有变量应该通过引用来传递"错误,因为在我使用的代码上有一行不会将explode()结果放入变量中。根据需要使用严格的PHP标准。

但是因为在While循环中使用了explode()函数,我无法想到一个合适的解决方案。

我的代码看起来像

    function user_exists($username) {
    rewind($this->fp);
        while(!feof($this->fp) && trim($lusername = array_shift(explode(":",$line = rtrim(fgets($this->fp)))))) {
            if($lusername == $username)
                return 1;
        }
    return 0;
}

有关如何解决此问题的任何建议?

1 个答案:

答案 0 :(得分:1)

我想也许你需要坐下来稍微分开你的代码并看看发生了什么。

首先,条件是!feof($this->fp)

来自manual

  

feof - 测试文件指针上的文件结尾

您会注意到的一件事是feof()只是一个返回truefalse的测试。它在循环结束时推进指针位置,所以在使用这个函数时,你的while循环中的其他地方需要有一些能够推进指针的东西,否则你将会有一个无限循环。

第二个条件是:

trim($lusername = array_shift(explode(":",$line = rtrim(fgets($this->fp)))))

从左到右的第一个函数是trim(),它返回string。从我们方便的花花公子comparison table我们看到,在执行if ((String) $var)时,当且仅当字符串为空(false)或数字零作为字符串时,它才会计算为"""0"),否则返回true。我个人倾向于非常讨厌使用if ((String) $var)(首先因为除非你很清楚你的比较表,否则对于新手来说有点不清楚,因为99%的人正在这样做,他们实际上是在检查字符串长度,在这种情况下我希望它为字符串true返回"0"。因此,假设您不需要它为false返回"0",我们可以将其更改为strlen($var) > 0,然后在循环内操作变量。这应该会大大简化这里的事情。

现在我们有:

while (!feof($this->fp) && strlen($var) > 0) { /*...*/ }

这将循环直到我们位于文件末尾或$var是空行。其他所有东西都可以卸载到while循环的主体中,因此更容易分开。

所以这就是我们现在所拥有的:

$line = rtrim(fgets($this->fp));
$lusername = array_shift(explode(":",$line)));

嗯,哦!那是“令人讨厌的”错误:

  

严格标准:只有变量应通过 /path/to/file.php x 行上的引用传递。

因此我们可以从这里看到,产生错误的部分不是explode(),而是array_shift()。另见:Strict Standards: Only variables should be passed by reference

这意味着,由于array_shift()修改了数组,因此需要引用它。由于您没有传递实际变量,而是传递函数的结果,因此PHP无法修改它。这类似于function($var) = 3;这样的事情。当然你不能这样做。相反,您需要将值保存到临时变量。所以现在我们有:

$line = rtrim(fgets($this->fp));
$split = explode(":",$line);
$lusername = array_shift($split);
哇哇!没有更多警告信息。

所以把它放在一起,我们现在有:

while (!feof($this->fp) && strlen($lusername) > 0) {
    $line = rtrim(fgets($this->fp));
    $split = explode(":",$line);
    $lusername = array_shift($split);
    if($lusername == $username) {
        return 1;
    }
}

此外,如前所述,fgets()会使指针前进,从而允许!feof($this->fp)语句中的while部分发生变化。