2016-04-08 43 views
0

我遇到了「只有變量應該通過引用傳遞」錯誤,因爲在我使用的代碼中有一行沒有放置explode()結果變成一個變量。根據需要使用嚴格的PHP標準。while循環:只有變量可以通過引用錯誤傳遞

但是因爲在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; 
} 

如何解決這個有什麼建議?

+2

你正在試圖將太多的方法塞進一行,因此,它不僅非常難以閱讀,而且很容易出錯,正如你所看到的。分手了。設置臨時變量,然後在while循環中使用它們。另外,你甚至不會在任何地方使用'$ line'(除非這不是這個方法的整個代碼),所以這可以被消除。 – Mike

+0

謝謝@Mike。關於如何最好地破解代碼的任何建議? 我試過了: $ temps = explode(「:」,rtrim(fgets($ this-> fp))); (!feof($ this-> fp)&& trim($ lusername = array_shift($ temps))){} 這確實解決了參考錯誤,但中斷了函數。 – Kaspar

回答

1

我想也許你需要坐下來休息一會兒,看看發生了什麼。

首先,條件是同時!feof($this->fp)

manual

feof — Tests for end-of-file on a file pointer

一件事,你將在這裏注意的是,feof()僅僅是一個測試,它返回truefalse。它確實在而不是在循環時提前指針位置,所以在使用此函數時,while循環中的其他位置需要有一些提示指針的地方,否則將會出現無限循環。

第二個條件是:從左至右

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

第一個功能是trim(),它返回一個string。從我們方便的Dandy comparison table我們看到,當做if ((String) $var)時,它的計算結果爲false當且僅當字符串爲空("")或數字零爲字符串("0"),否則返回true。我個人傾向於非常討厭使用if ((String) $var)(首先,因爲它對新手來說有點不清楚,除非你知道你的對照表和第二,因爲99%的人在做他們實際上正在檢查字符串長度的情況,在這種情況下,我會希望它對於字符串"0"返回true)。因此,假設您不需要它返回false"0"我們可以將其更改爲strlen($var) > 0然後操作循環內的變量。這應該大大簡化這裏的事情。

所以現在我們有:

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

這將遍歷,直到我們在文件的結尾或$var是一個空行。其他任何東西都可以卸載到while循環的主體中,因此分離起來更容易。

因此,這是我們現在有:

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

嗯,哦!有說「討厭」的錯誤:

Strict Standards: Only variables should be passed by reference in /path/to/file.php on line 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()會提前指針,它允許在while語句來改變!feof($this->fp)部分。

相關問題