2014-06-07 54 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'。我知道数据是有效的和适当的结构,因为当我使用“空”数组时,一切正常。你的建议改善了我的逻辑,但我仍然坚持一个“空的”完整数组...... –