【问题标题】:Full array evaluating as empty and null完整数组评估为空和 null
【发布时间】:2014-07-28 18:49:43
【问题描述】:

我有一个非常奇怪的问题,我一直无法找到答案。我有一个 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,我会检查以确保数组没有作为 null 或空返回,然后对数据进行排序。

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 

我猜这与我的整个数组以某种方式被评估为空和 null 的事实有关,即使它不是。

【问题讨论】:

    标签: php arrays csv usort


    【解决方案1】:

    你这样说:

    ...并通过引用变量将数组传回...

    还有这个:

    如果函数返回为真,我会检查以确保数组 没有作为 null 或空传回,然后对数据进行排序。

    你为什么要这样做?如果您正在检查truefalse,那么检查它是null 还是empty 它的值是多少?只需检查它是 null 还是 empty,只需执行以下操作即可:

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

    然后去掉界面中$array的引用返回:

    function ReadCsvDataIntoArray($path, &$headers, $array, $idFilter = NULL){ 
    

    您的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 {
    

    但是你这么说;强调我的:

    我有一个 PHP 函数,可以将 CSV 数据读入一个数组,然后 返回 如果数据被成功读取,则为 true

    没有。您的逻辑不检查数据是否已成功读取。如果文件本身可以读取,您的逻辑只会返回true。这并不意味着文件本身的 contents 是有效的。你检查过文件本身吗?或者您是否检查了这一行:

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

    实际上通过这样的操作在$row 中有值?

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

    我认为您的 CSV 可能存在行格式问题。就像它保存在 Windows 机器上,但现在正在 Mac OS X 或 Linux 机器上读取,反之亦然。在fgetcsv 的文档中查看此内容:

    注意:如果 PHP 在读取时没有正确识别行尾 在 Macintosh 计算机上或由 Macintosh 计算机创建的文件,启用 auto_detect_line_endings 运行时配置选项可能会有所帮助 解决问题。

    因此,也许可以像这样将启用auto_detect_line_endings 的这一行添加到您的函数中:

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

    【讨论】:

    • 我认为这也可能是问题所在,但是按照您的建议将数组作为返回变量时,我仍然得到相同的结果。
    • @ReedRaymond 够公平的。引用只是让我感到困惑,在这种情况下真的是多余的,所以我仍然坚持你返回一个数组并检查它是否为空。也就是说,检查我的最新编辑。您的 true 逻辑不是基于 CSV 数据是否实际被解析,而仅基于文件本身是否可读。能够读取文件和能够解析内容是两件不同的事情。所以我相信你的 CSV 可能有行格式问题。检查我当前的编辑,围绕我说的地方,“但你这么说:”
    • 这个信息很有帮助。我同意将数组作为返回变量传递更有意义。我还检查了数组在返回之前在ReadCsvDataIntoArray() 内评估!empty,在返回之后评估empty。我知道数据是有效的并且结构正确,因为当我使用“空”数组时一切正常。您的建议改善了我的逻辑,但我仍然坚持使用“空”完整数组...
    • “数组在返回之前在 ReadCsvDataIntoArray() 内计算 !empty,在返回后计算 empty。”好的,这是一个疯狂的想法:可能是 $array 太通用了,您在这里将其用作参考,因此您的代码中的其他内容可能会覆盖它。因此,只需将 $array 重命名为 $csv_array in function ReadCsvDataIntoArray( 之类的其他名称,然后尝试。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-21
    • 1970-01-01
    • 1970-01-01
    • 2018-06-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多