使用 PHP 在两个 csv 文件之间实现左连接

2024-02-18

由于该解决方案是根据投票良好的答案改编的别处 https://stackoverflow.com/a/25837426,我没想到会遇到问题。

问题:我想要LEFT JOIN 文件0.csv https://www.dropbox.com/s/gx1oyfj03dsn45p/file0.csv?dl=0 with 文件1.csv https://www.dropbox.com/s/40zndvtmm2azctg/file1.csv?dl=0.

文件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 |
+-----------------+-------------+--------------+--------+--------+--------+-------+-------+

PHP 函数LEFT JOIN file0.csv with file1.csv on Manufacturer ID and 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 |
    +-----------------+-------------+--------------+--------+--------+--------+-------+-------+
  

尽管有 2 行没有连接,但为什么file0."Manufacturer ID" = file1.mpn满意吗?


我将把它简化为SSCCE http://sscce.org/所以很容易理解和重现。

我认为你在这里的解决方案过于复杂,这可能是导致你出现这么多奇怪错误的原因。解决方案实际上相当简单。您需要做的就是获取每个 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 |
  
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 PHP 在两个 csv 文件之间实现左连接 的相关文章

  • Readfile 从大文件中读取 0 字节?

    我正在尝试通过以下方式发送一个大文件readfile 但是 没有任何内容发送到浏览器 并且readfile 回报0 not false 我尝试发送的文件大小为 4GiB 并且可由 PHP 读取 我正在设置set time limit 0 以
  • 如何将变量插入 PHP 数组?

    我在网上查了一些答案 但都不是很准确 我希望能够做到这一点 id result id info array id Example echo info 0 这有可能吗 您需要的是 不推荐 info array id Example varia
  • 在 PHP 中包含 PHP 文件

    我有一个网站 它运行 PHP if 语句来根据附加文件的类型 即 Jpg Txt MP4 显示内容 所以我显示 TXT 文件的代码是 if post attachment txt display attachment div class d
  • Ajax 没有将我重定向到下一页

    我正在尝试将单击的图像的 ID 传递到下一页 当我开发代码时 它没有将我重定向到下一页 当我单击 F12 并检查网络中的 POST 时 它显示变量已正确传递到下一页 如附图所示 但它没有将我重定向到下一页 所以现在我知道变量在下一页中正确传
  • 尝试使用 php 发送 POST 请求,无论我做什么,我都会收到“HTTP ERROR 500”

    为了发出 HTTP 请求 有人建议我尝试使用 PHP 并给了我一段代码 url https example com dashboard api data array to gt PHONE NUMBER from gt SENDER ID
  • get url 重定向时 File_get_contents() 不起作用

    我正在使用的功能是 function http post url data data url http build query data data len strlen data url date default timezone set
  • PHP 无法打开流:是一个目录

    非常简单的 PHP 脚本 我在我亲自设置的 Ubuntu Web 服务器上的 EE 模板中运行 我知道这与权限有关 并且我已经将我尝试写入的目录的所有者更改为 Apache 用户 我得到的错误是 遇到 PHP 错误 严重性 警告 消息 fi
  • php中的条件格式化html表与时间戳比较

    echo table style width 100 tr echo td Order td echo td Destination td echo td Location td echo td Status td echo td Time
  • 如何隐藏 URL 中的锚标记

    如何隐藏地址栏中以下链接 href 的哈希值 a href index php dev name 所以它会将我重定向到index php dev name 但我希望地址栏只显示index php 您可以使用 Javascript oncli
  • 使用从两列计算出的键对 CSV 进行排序,获取前 n 个最大值

    这里是 Python 业余爱好者 假设这里我有一个示例 csv 文件的片段 Country Year GDP Population Country1 2002 44545 24352 Country2 2004 14325 75677 Co
  • 媒体的 Google Cloud Storage 签名网址

    我已经建立了一个视频网站 为用户提供 m3u8 和关联的 ts 文件 我不希望媒体文件免费可用 所以我所做的是 当用户在网站上时 在 mysql 中使用他们的 IP 和令牌创建一个会话 当他们请求特定媒体子域 mp4 domain com
  • 编辑 HTACCESS 文件以防止直接访问特定文件夹中的特定文件

    我试图阻止直接访问子文件夹中的特定文件 我意识到这个论坛上有很多描述类似问题的主题 但是 我的似乎有点尴尬 由于我已经存在 HTACCESS 文件 这是文件的文件路径 www example com PRINCIPAL PROJECTS m
  • 如何纠正这个非法字符串偏移?

    我收到此错误 警告 第 32 行 home mysite public html wp content themes evento lib php extra class php 中的非法字符串偏移 type 我意识到文件中的这部分代码是错
  • PHP 扩展开发入门 [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 请推荐有关 PHP 低 级 modules 编程接口的帮助文章或教程 搜索我的书签 我发现的唯一链接是
  • 如何通过php获取网页的Open Graph协议?

    PHP 有一个简单的命令来获取网页的元标记 get meta tags 但这仅适用于具有名称属性的元标记 然而 开放图谱协议如今变得越来越流行 从网页获取 opg 值的最简单方法是什么 例如 我看到的基本方法是通过 cURL 获取页面并使用
  • Codeigniter - 出现 404 Not Found 错误

    我们在 godaddy 有两个托管套餐 我们的实时网站使用以下 htaccess 文件运行良好 无需在 url 中使用 index php 即可访问网站 RewriteEngine On RewriteCond REQUEST FILENA
  • 如何删除文件

    我们有一个脚本 scripts ourscript php和一个文件 media movie1 flv 当我们运行时 我们如何删除这个文件ourscript php Using unlink http php net manual en f
  • 反向引用在 PHP 中不起作用

    最近我一直在研究 更多的是在实践中说实话 正则表达式 我注意到他的力量 我提出的这个要求 link https stackoverflow com questions 30380397 take the text up to a speci
  • 如何清除 APC 缓存而不使 Apache 崩溃?

    如果 APC 存储大量条目 清除它们会导致 httpd 崩溃 如果 apc clear cache user 花费的时间超过 phps max execution time 调用 apc clear cache 的脚本 将在之前被 php
  • 如何使用 php 将 *.xlsb 转换为数组或 *.csv

    我正在尝试转换 xlsb文件到php array or csv文件 或至少 xls 我尝试使用PHPExcel 但看起来它无法识别该文件中的内容 我注意到 你可以重命名 xlsb文件到 zip文件 然后使用命令行解压缩unzip zip 之

随机推荐