由于此解决方案改编自投票得很好的答案 elsewhere ,我没想到会遇到问题。
问题:我想LEFT JOIN
file0.csv与 file1.csv .
文件0.csv
+-----------------+-------------+--------------+
| Manufacturer ID | image | description |
+-----------------+-------------+--------------+
| SKU231 | image1.jpg | A box. |
| SKUAG1 | image22.jpg | Another box. |
| SKU21D | image7a.png | A third box. |
+-----------------+-------------+--------------+
文件 1.csv:
+--------+--------+--------+-------+-------+
| mpn | length | height | width | title |
+--------+--------+--------+-------+-------+
| SKU231 | 22 | 14 | 10 | Box 1 |
| SKUAG1 | 12 | 6 | 6 | Box 2 |
| SKU21D | 5 | 8 | 5 | Box 3 |
+--------+--------+--------+-------+-------+
期望的结果(file2.csv):
+-----------------+-------------+--------------+--------+--------+--------+-------+-------+
| Manufacturer ID | image | description | mpn | length | height | width | title |
+-----------------+-------------+--------------+--------+--------+--------+-------+-------+
| SKU231 | image1.jpg | A box. | SKU231 | 22 | 14 | 10 | Box 1 |
| SKUAG1 | image22.jpg | Another box. | SKUAG1 | 12 | 6 | 6 | Box 2 |
| SKU21D | image7a.png | A third box. | SKU21D | 5 | 8 | 5 | Box 3 |
+-----------------+-------------+--------------+--------+--------+--------+-------+-------+
LEFT JOIN
的 PHP 函数 file0.csv
与 Manufacturer ID
和 上的
分别为:file1.csv
mpn
function my_csv_join(array $csv_input_file_array, $csv_output_file, $html_preview, $left_join_on, $right_join_on = NULL) {
if (count($csv_input_file_array) > 2) {
echo 'This function probably only works for 2 csv files being joined at a time. Reapply iteratively if needed. Exiting now.';
exit;
} else {
for ($x = 0; $x <= 1; $x++) {
//get csv file to array
${'file' . $x} = fopen($csv_input_file_array[$x], "r"); //Dynamic variables using braces: https://stackoverflow.com/a/9257536/9095603
while (!feof(${'file' . $x})) {
${'csv_array' . $x}[] = fgetcsv(${'file' . $x});
}
fclose(${'file' . $x});
${'csv_array' . $x} = array_filter(${'csv_array' . $x}); // gets rid of last empty array in case present
//CREATE HEADERED ARRAY
${'header' . $x} = array_shift(${'csv_array' . $x});
foreach (${'csv_array' . $x} as ${'product_data_array' . $x} {
${'headered_array' . $x}[] = array_combine(${'header' . $x}, ${'product_data_array' . $x});
}
}
// How to simulate the SQL LEFT JOIN operation using PHP arrays? https://stackoverflow.com/a/25837426
//function to simulate the left join
$left = $headered_array0;
$right = $headered_array1;
$final = array();
if (empty($right_join_on)) // if $right_join_on omitted implies $right_join_on has the same value as $left_join_on
$right_join_on = $left_join_on;
foreach ($left AS $k => $v) {
$final[$k] = $v; //basically keeping everything; $left just becomes $final
foreach ($right AS $kk => $vv) {
if ($v[$left_join_on] == $vv[$right_join_on]) {
foreach ($vv AS $key => $val)
$final[$k][$key] = $val;
} else {
foreach ($vv AS $key => $val)
$final[$k][$key] = NULL;
}
}
}
if ($html_preview == 'y') {
echo '<pre>';
var_dump($final);
echo '</pre>';
}
// REINSTATE HEADERS
// var_dump($final[0]);
$indented_header = array(
0 => array_keys($final[0])
);
$re_headered_array = array_merge($indented_header, $final);
// write array to csv file
$file2 = fopen($csv_output_file, "w");
foreach ($re_headered_array as $line) {
fputcsv($file2, $line);
}
fclose($file2);
}
}
调用函数 my_csv_join()
:
my_csv_join(array('C:\xampp\htdocs\kalugi\file0.csv','C:\xampp\htdocs\kalugi\file1.csv'), 'C:\xampp\htdocs\kalugi\file2.csv','y','Manufacturer ID','mpn');
实际结果显示并非所有在 file0."Manufacturer ID"= file1.mpn
上匹配的记录都被匹配。因此,一些满足连接条件的预期行未被连接。我们用 NULL
代替它们的值:
var_dump
结果:
array(3) {
[0]=>
array(8) {
["Manufacturer ID"]=>
string(6) "SKU231"
["image"]=>
string(10) "image1.jpg"
["description"]=>
string(6) "A box."
["mpn"]=>
NULL
["length"]=>
NULL
["height"]=>
NULL
["width"]=>
NULL
["title"]=>
NULL
}
[1]=>
array(8) {
["Manufacturer ID"]=>
string(6) "SKUAG1"
["image"]=>
string(11) "image22.jpg"
["description"]=>
string(12) "Another box."
["mpn"]=>
NULL
["length"]=>
NULL
["height"]=>
NULL
["width"]=>
NULL
["title"]=>
NULL
}
[2]=>
array(8) {
["Manufacturer ID"]=>
string(6) "SKU21D"
["image"]=>
string(11) "image7a.png"
["description"]=>
string(12) "A third box."
["mpn"]=>
string(6) "SKU21D"
["length"]=>
string(1) "5"
["height"]=>
string(1) "8"
["width"]=>
string(1) "5"
["title"]=>
string(5) "Box 3"
}
}
写到 $file2 (file2.csv) 的结果:
+-----------------+-------------+--------------+--------+--------+--------+-------+-------+ | Manufacturer ID | image | description | mpn | length | height | width | title | +-----------------+-------------+--------------+--------+--------+--------+-------+-------+ | SKU231 | image1.jpg | A box. | | | | | | | SKUAG1 | image22.jpg | Another box. | | | | | | | SKU21D | image7a.png | A third box. | SKU21D | 5 | 8 | 5 | Box 3 | +-----------------+-------------+--------------+--------+--------+--------+-------+-------+
尽管 file0."Manufacturer ID"= file1.mpn
已满足,但为什么有 2 行没有连接?
最佳答案
我将把它简化为 SSCCE所以它很容易理解和重现。
我认为您在这里使解决方案过于复杂,这可能是导致您出现如此多奇怪错误的原因。解决方法其实很简单。您需要做的就是获取每个 csv 文件,将其解析为行和列,然后将这些行中的每一行合并为一行以将其写回另一个 csv。
这是最简单的方法:
$file0 = <<<'FILE0'
Manufacturer ID,image,description
SKU231,image1.jpg,A box.
SKUAG1,image22.jpg,Another box.
SKU21D,image7a.png,A third box.
FILE0;
$file1 = <<<'FILE1'
mpn,length,height,width,title
SKU231,22,14,10,Box 1
SKUAG1,12,6,6,Box 2
SKU21D,5,8,5,Box 3
FILE1;
$csv1 = array_map('str_getcsv', explode("\n", $file0));
$csv2 = array_map('str_getcsv', explode("\n", $file1));
$fd = fopen("/tmp/test.csv", 'w');
foreach ($csv1 as $row => $columns) {
$newRow = array_merge($columns, $csv2[$row]);
fputcsv($fd, $newRow);
}
$fd = fopen("/tmp/test.csv", "r");
while (($line = fgets($fd)) !== false) {
echo $line;
}
结果:
"Manufacturer ID",image,description,mpn,length,height,width,title SKU231,image1.jpg,"A box.",SKU231,22,14,10,"Box 1" SKUAG1,image22.jpg,"Another box.",SKUAG1,12,6,6,"Box 2" SKU21D,image7a.png,"A third box.",SKU21D,5,8,5,"Box 3"
|Manufacturer ID | image | description | mpn | length | height | width | title | |----------------|-------------|--------------|--------|--------|--------|-------|-------| | SKU231 | image1.jpg | A box. | SKU231 | 22 | 14 | 10 | Box 1 | | SKUAG1 | image22.jpg | Another box. | SKUAG1 | 12 | 6 | 6 | Box 2 | | SKU21D | image7a.png | A third box. | SKU21D | 5 | 8 | 5 | Box 3 |
关于php - 在两个 csv 文件之间用 PHP 实现左连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59921093/