重复出现单一错误但几乎完全成功 array_combine: Warning: array_combine() expects parameter 2 to be array, boolean

Single error iterated but almost fully successful array_combine: Warning: array_combine() expects parameter 2 to be array, boolean

Here is 与此问题相关的完整 csv 文件。

我不明白怎么报错

Warning: array_combine() expects parameter 2 to be array, boolean given in C:\xampp\htdocs\kalugi\auscomp\test.php on line 18

在这种情况下适用于:

<?php
    // Set header
    function set_header($csv_input, $html_preview) {
        $file = fopen($csv_input, "r");
        while (!feof($file)) {
            $csv_array[] = fgetcsv($file);
        }
        $header = array_shift($csv_array);
        foreach ($csv_array as $product) {
            $headered_array[] = array_combine($header, $product);
        }
        //print_r
        if ($html_preview = 'y') {
            echo '<pre>';
            print_r($headered_array);
            echo '</pre>';
        }
    }

    set_header('ACDataFeed.csv', 'y');
Edit: Every iteration of `print_r($header); print_r($product);` within foreach() loop reveals that both are arrays of the same size:

        Array
    (
        [0] => No_
        [1] => Manufacturer ID
        [2] => Description
        [3] => LQ Price
        [4] => Retail Price Incl_ GST
        [5] => AvailableQty
        [6] => Rocklea
        [7] => Sydney
        [8] => Net Weight
        [9] => Item Category Code
        [10] => Product Group Code
        [11] => Minor Category 1
        [12] => Minor Category 2
        [13] => Vendor Name
        [14] => Vendor URL
        [15] => Item URL
        [16] => Warranty
        [17] => Dimension
        [18] => Description1
        [19] => Image
    )
    Array
    (
        [0] => II00570
        [1] => AUSC00008
        [2] => GNR CAB USB-A-B-5M
        [3] => 6.00000000000000000000
        [4] => 18.00000000000000000000
        [5] => 2.00000000000000000000
        [6] => 1.00000000000000000000
        [7] => 1.00000000000000000000
        [8] => 0.01000000000000000000
        [9] => GNR
        [10] => CAB
        [11] => CAB-USB
        [12] => #
        [13] => 
        [14] => 
        [15] => 
        [16] => 
        [17] => 
        [18] => Generic USB2.0 A-Male to B-Male Printer Cable - 5m

        [19] => https://accomputers.com/uploads/image/GNR-CAB-USB-A-B-5M.jpg
    )

I've considered this through and I'm geniunely unable to see the error here.  How is this false for an array?

编辑 2:然而 array_combine 是成功的,尽管它上面出现了错误。你可以看到下面的数组 $header 和数组 $product 成功结合,尽管有错误:

Warning: array_combine() expects parameter 2 to be array, boolean given in C:\xampp\htdocs\kalugi\auscomp\test.php on line 18

Array
(
    [0] => Array
        (
            [No_] => II00570
            [Manufacturer ID] => AUSC00008
            [Description] => GNR CAB USB-A-B-5M
            [LQ Price] => 6.00000000000000000000
            [Retail Price Incl_ GST] => 18.00000000000000000000
            [AvailableQty] => 2.00000000000000000000
            [Rocklea] => 1.00000000000000000000
            [Sydney] => 1.00000000000000000000
            [Net Weight] => 0.01000000000000000000
            [Item Category Code] => GNR
            [Product Group Code] => CAB
            [Minor Category 1] => CAB-USB
            [Minor Category 2] => #
            [Vendor Name] => 
            [Vendor URL] => 
            [Item URL] => 
            [Warranty] => 
            [Dimension] => 
            [Description1] => Generic USB2.0 A-Male to B-Male Printer Cable - 5m

            [Image] => https://auscompcomputers.com/uploads/image/GNR-CAB-USB-A-B-5M.jpg
        )

    [1] => Array
        (
            [No_] => II00693
            [Manufacturer ID] => M6
            [Description] => ITR KBD M6-PS2-WHT
            [LQ Price] => 8.50000000000000000000
            [Retail Price Incl_ GST] => 24.00000000000000000000
            [AvailableQty] => 202.00000000000000000000
            [Rocklea] => 200.00000000000000000000
            [Sydney] => 2.00000000000000000000
            [Net Weight] => 0.50000000000000000000
            [Item Category Code] => ITR
            [Product Group Code] => KBD
            [Minor Category 1] => KBD-WIRED
            [Minor Category 2] => KBD-SINGLE
            [Vendor Name] => 
            [Vendor URL] => 
            [Item URL] => 
            [Warranty] => 
            [Dimension] => 
            [Description1] => Itron M6 Keyboard, PS2 Beige

            [Image] => https://auscompcomputers.com/uploads/image/ITR-KBD-M6-PS2-WHT.jpg
        )

为了完整性,这里是调试输出:

foreach($csv_array as $product) {
//      $csv_array[][1]
        $headered_array[] = array_combine($header,$product);
        echo '<pre>';
        var_dump($header);
        var_dump($product);
        echo '</pre>';
    }

var_dumps:

array(20) {
  [0]=>
  string(3) "No_"
  [1]=>
  string(15) "Manufacturer ID"
  [2]=>
  string(11) "Description"
  [3]=>
  string(8) "LQ Price"
  [4]=>
  string(22) "Retail Price Incl_ GST"
  [5]=>
  string(12) "AvailableQty"
  [6]=>
  string(7) "Rocklea"
  [7]=>
  string(6) "Sydney"
  [8]=>
  string(10) "Net Weight"
  [9]=>
  string(18) "Item Category Code"
  [10]=>
  string(18) "Product Group Code"
  [11]=>
  string(16) "Minor Category 1"
  [12]=>
  string(16) "Minor Category 2"
  [13]=>
  string(11) "Vendor Name"
  [14]=>
  string(10) "Vendor URL"
  [15]=>
  string(8) "Item URL"
  [16]=>
  string(8) "Warranty"
  [17]=>
  string(9) "Dimension"
  [18]=>
  string(12) "Description1"
  [19]=>
  string(5) "Image"
}
array(20) {
  [0]=>
  string(7) "II00570"
  [1]=>
  string(9) "AUSC00008"
  [2]=>
  string(18) "GNR CAB USB-A-B-5M"
  [3]=>
  string(22) "6.00000000000000000000"
  [4]=>
  string(23) "18.00000000000000000000"
  [5]=>
  string(22) "2.00000000000000000000"
  [6]=>
  string(22) "1.00000000000000000000"
  [7]=>
  string(22) "1.00000000000000000000"
  [8]=>
  string(22) "0.01000000000000000000"
  [9]=>
  string(3) "GNR"
  [10]=>
  string(3) "CAB"
  [11]=>
  string(7) "CAB-USB"
  [12]=>
  string(1) "#"
  [13]=>
  string(0) ""
  [14]=>
  string(0) ""
  [15]=>
  string(0) ""
  [16]=>
  string(0) ""
  [17]=>
  string(0) ""
  [18]=>
  string(56) "Generic USB2.0 A-Male to B-Male Printer Cable - 5m
"
  [19]=>
  string(65) "https://auscompcomputers.com/uploads/image/GNR-CAB-USB-A-B-5M.jpg"
}

正如您将在以下解决方案中看到的那样,这是一个非常好的问题。

当使用 PHP 的内置 csv 到数组函数(例如 fgetcsv)时,最后的冗余行终止符实际上会导致写入一个空数组,这是 csv 文件的一个常见缺陷,这些函数是非常基本,不要考虑这些事情。

来自 PHP array_combine 手册:

5.4.0 Previous versions issued E_WARNING and returned FALSE for empty arrays.

这与编译数组的整个 foreach 循环仅返回错误 一次 的事实相符,因为 csv 末尾只有一个空数组文件。它还解释了为什么 array_combined 实际上除了最后一个元素案例之外的所有案例都成功了。

看到最后一个数组是空的:

...
    [8405] => Array
        (
            [No_] => II38392
            [Manufacturer ID] => 7XB7A00034
            [Description] => LEN HDD SAS-1TB-7XB7A00034
            [LQ Price] => 336.00000000000000000000
            [Retail Price Incl_ GST] => 480.48000000000000000000
            [AvailableQty] => 0.00000000000000000000
            [Rocklea] => 
            [Sydney] => 
            [Net Weight] => 0.50000000000000000000
            [Item Category Code] => LEN
            [Product Group Code] => HDD
            [Minor Category 1] => HDD-2.5
            [Minor Category 2] => HDD-ENT
            [Vendor Name] => Lenovo
            [Vendor URL] => 
            [Item URL] => 
            [Warranty] => 3 Years
            [Dimension] => 
            [Description1] => Lenovo 7XB7A00034, ThinkSystem 2.5" 1TB 7.2K SAS 12Gb Hot Swap 512n HDD, 3 Years

            [Image] => https://auscompcomputers.com/uploads/image/LEN-HDD-SAS-1TB-7XB7A00034.jpg
        )

    [8406] => 
    )

解决方案 - 先处理文件,然后再将其传递给任何其他函数:

function remove_last_n($csv_input){
    //remove the very last newline to prevent a 0-field array for the last line
    $str = file_get_contents($csv_input);
    $str = preg_replace('/\n$/', '', $str);
    file_put_contents("$csv_input",$str);
}
remove_last_n('whatever_file.csv');