2014-06-07 25 views
1

我有一個非常奇怪的問題,我一直無法找到答案。我有一個PHP函數讀取CSV數據到一個數組,然後如果數據被成功讀取返回true,並通過引用變量全陣列評估爲空和空

function ReadCsvDataIntoArray($path, &$headers, &$array, $idFilter = NULL){  
    if(file_exists($path)){ 
     $fh = fopen($path, 'r'); 
     if($fh){ 
      $headers = fgetcsv($fh); 
      $rowIdx = 0; 
      while($row = fgetcsv($fh)){ 
       $addRow = true; 
       if($idFilter != NULL){  
        if(isset($row[0])){ 
         if(!in_array($row[0], $idFilter)){ 
          $addRow = false; 
         } 
        } 
       } 
       if($addRow){ 
        $colIdx = 0; 
        foreach($row as $val){  
         $array[$rowIdx][$headers[$colIdx]] = $val; 
         $colIdx++; 
        } 
        $rowIdx++;      
       } 
      }   
      fclose($fh); 
      return true; 
     } else { 
      echo "Unable to open file: ".$path; 
     } 
    } else { 
     echo "CSV doesn't exist: ".$path; 
    } 
    return false; 
} 

傳遞陣列後面如果函數返回true,則我檢查,以確保該數組沒有被傳回爲空或空,然後對數據進行排序。

if($this->ReadCsvDataIntoArray($client_library_path, $headers, $CSVdata, $log)){ 
    if($CSVData != NULL){ 

      usort($CSVdata, create_function('$a, $b', 'return $a["engagement"] < $b["engagement"];')); 

     // Do stuff with the sorted array 

    } else { 
      echo "CSV data is NULL.\n"; 
    } 

我不斷收到「CSV數據爲NULL」。如果我將邏輯更改爲if($CSVData == NULL)甚至if(empty($CSVData)),它將輸入if語句,嘗試對數組進行排序(儘管if聲明爲空),並嘗試對數據進行排序。

這是我的第二個問題來自於這usort工作在我的本地:

usort($CSVdata, function($a, $b) { return $a["scheduled"] < $b["scheduled"]; }); 

,但它不工作在服務器上的,因爲它的PHP版本,所以我把它改成:

usort($CSVData, create_function('$a, $b', 'return $a["scheduled"] < $b["scheduled"];')); 

但隨着create_function版本usort我收到此錯誤信息

Warning: usort(): The argument should be an array 

我猜這與我的完整數組在某種程度上被評估爲空和空的事實有關,即使它不是。

回答

0

你這樣說:

...並通過引用變量傳遞陣列回來...

而且這樣的:

如果函數返回true,則我檢查,以確保數組 未被傳回爲空或空,然後對數據進行排序。

你爲什麼這樣做?如果您正在檢查truefalse然後檢查它是否是nullempty那是什麼值?只是檢查,如果它是這樣做,而不是nullempty

 // return true; 
     return $array; 
    } else { 
     echo "Unable to open file: ".$path; 
    } 
} else { 
    echo "CSV doesn't exist: ".$path; 
} 
// return false; 
return $array; 

然後擺脫界面返回引用爲$array的:

truefalse邏輯可能打破&不值得正確處理。但是,如果值重新返回nullempty,那麼爲什麼花時間重新發明輪子,這就是您正在採取的行動。

還可以再調整這個$CSVData邏輯,以適應新的結構:

$CSVData = $this->ReadCsvDataIntoArray($client_library_path, $headers, $CSVdata, $log); 

if(!empty($CSVData)){ 

     usort($CSVdata, create_function('$a, $b', 'return $a["engagement"] < $b["engagement"];')); 

    // Do stuff with the sorted array 

} else { 
     echo "CSV data is empty.\n"; 
} 

而且,你的整個return true邏輯嚴格基於本身可以打開的文件:

$fh = fopen($path, 'r'); 
    if($fh){ 
     // Code removed for structural illustration purposes. 
     // ... 
     // ... 
     fclose($fh); 
     return true; 
    } else { 

但你說這個; empahsis礦:

我有一個PHP函數讀取CSV數據到一個數組,然後返回真正 如果數據被成功讀取 ...

號你的邏輯不檢查數據被成功讀取。你的邏輯簡單地返回true如果文件本身可以被讀取。這並不意味着文件本身的內容有效。你檢查過這個文件嗎?或者你檢查是否這行:

while($row = fgetcsv($fh)){ 

其實在$row通過做類似這樣的值?

echo '<pre>'; 
print_r($row); 
echo '</pre>'; 

我想也許你的CSV有行格式問題。就像它保存在Windows機器上一樣,但現在正在Mac OS X或Linux機器上讀取,或者反過來讀取它。看看這個文檔中的fgetcsv

注:如果在讀 文件打開或創建時的Macintosh計算機,使 auto_detect_line_endings運行時配置選項可以幫助PHP沒有正確認識到行結束 解決問題。

因此,也許加入這行讓auto_detect_line_endings給你的函數是這樣的:

function ReadCsvDataIntoArray($path, &$headers, &$array, $idFilter = NULL){ 
    ini_set("auto_detect_line_endings", true); 
+0

我想這可能是這個問題爲好,但得到的數組作爲返回變量時,我仍然得到同樣的結果如你所建議的。 –

+1

@ReedRaymond夠公平的。引用只是讓我迷惑,在這種情況下真的是多餘的,所以我仍然堅持你返回一個數組並檢查它是否爲空。這就是說,檢查我最近的編輯。你的'true'邏輯不是基於CSV數據是否實際解析,而僅僅取決於文件本身是否可讀。能夠讀取文件並能夠解析內容是兩件不同的事情。所以我相信你的CSV可能有行格式問題。在我所說的地方查看我當前的編輯,「但是你這樣說:」 – JakeGould

+1

此信息非常有幫助。我同意將數組作爲返回變量傳遞更合理。我也檢查過,在返回之前,數組在'ReadCsvDataIntoArray()'內部被賦值'!empty',並在返回之後被賦值爲'empty'。我知道數據是有效的和適當的結構,因爲當我使用「空」數組時,一切正常。你的建議改善了我的邏輯,但我仍然堅持一個「空的」完整數組...... –