Повторяется одна ошибка, но почти полностью успешно array_combine: Предупреждение: array_combine() ожидает, что параметр 2 будет массивом, логическим
Вот полный CSV-файл, к которому относится эта проблема.
Я не понимаю как ошибка
Предупреждение: array_combine() ожидает, что параметр 2 будет массивом, логическим значением, указанным в C:\xampp\htdocs\kalugi\auscomp\test.php в строке 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"
}
2 ответа
Это действительно хороший вопрос, как вы увидите в следующем решении.
Распространенной ошибкой файлов csv является то, что избыточный указатель конца строки в конце фактически вызывает запись пустого массива при использовании встроенных в PHP функций преобразования csv в массив, таких как fgetcsv, которые очень просты и не принимают во внимание такие вещи.
Из руководства PHP для array_combine:
5.4.0 Предыдущие версии выдавали E_WARNING и возвращали FALSE для пустых массивов.
Это соответствует тому факту, что ошибка была возвращена только один раз для всего цикла foreach, который компилировал массив, поскольку в конце файла csv был только один пустой массив. Это также объясняет, почемуarray_combined
на самом деле удалось выполнить все, кроме последнего элемента case.
Посмотрите, что последний массив пуст:
...
[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');
См. объяснение пользователя 136649.
в моем случае мне нужен массив перед тем, как поместить его в файл, поэтому я сделал следующее и проверил последнюю пустую строку
$stream = fopen('filepath', 'r');
if ($stream) {
$header = [];
$count = 0;
while (!feof($stream)) {
$row = fgetcsv($stream, 0, ';');
if (empty($header)) {
$header = $row;
} elseif (empty($row)) {
continue;
} else {
$csv[] = array_combine($header, $row);
}
}
} else {
throw new Exception($stream . ' doesn`t exist or is not readable.');
}
fclose($stream);