php中的多个数组用于csv导出

时间:2018-04-22 19:12:31

标签: php arrays

我正在尝试将多个数组输出到带有预设标头的csv文件中。到目前为止,我只能设法将2个完全相同的结果输出到csv(sql result 0)。我相信我有我的"因为#34;在某种程度上混乱的陈述,并相信这可能很容易修复,但因为我的生活不能看到它。有没有人有任何想法,或任何更好的方式来做这个csv输出?

// output headers so that the file is downloaded rather than displayed
header('Content-type: text/csv');
header('Content-Disposition: attachment; filename="SageImport.csv"');

// do not cache the file
header('Pragma: no-cache');
header('Expires: 0');

// create a file pointer connected to the output stream
$file = fopen('php://output', 'w');

// send the column headers
fputcsv($file, array('Reference', 'Company Name', 'Currency', 'Credit Limit', 'Main Address Type', 'Main Address Line 1', 'Main Address Line 2', 'Main Address Town', 'Main Address County', 'Main Address Post Code', 'Main Address Country', 'Main Contact Name', 'Main Contact Phone', 'Main Contact Type', 'Main Contact Mobile', 'Main Contact Email', 'Main Contact Fax', 'Address 2 Type', 'Address 2 Line 1', 'Address 2 Line 2', 'Address 2 Town', 'Address 2 County', 'Address 2 Post Code', 'Address 2 Country', 'VAT Number', 'Ledger Account', 'Payment Terms', 'Notes', 'Bank Account Name', 'Bank Account Sort Code', 'Bank Account Number', 'Bank Account IBAN', 'Bank Account BIC'
));

$query = "SELECT * FROM clients WHERE sageexport='0'";
$result = mysql_query($query) or die("Error: ".mysql_error());
while ($row = mysql_fetch_array($result, MYSQL_NUM)) {$info[] = $row;}
for ($i = 0; $i < count($info); $i++) {
    if ($info[$i][10] = "yes") {$agreed = 'Agreement';}     
$data = array($info[$i][1], $info[$i][2], 'GBP', '', '', $info[$i][3], '', $info[$i][4], $info[$i][5], $info[$i][6], 'GB', '', $info[$i][8], '', '', $info[$i][7], '', '', '', '', '', '', '', '', '', '10001', '10', $agreed, '', '', '', '', '');
}
$agreed = "";


// output each row of the data
for ($i = 0; $i < count($info); $i++) {
foreach (array($data) as $row2){fputcsv($file, $row2);}
}
exit();

2 个答案:

答案 0 :(得分:2)

你得到同一行两次,因为你每次用这一行覆盖$data第一个循环:

$data = array($info[$i][1], $info[$i][2], 'GBP', '', '', $info[$i][3], '', $info[$i][4], $info[$i][5], $info[$i][6], 'GB', '', $info[$i][8], '', '', $info[$i][7], '', '', '', '', '', '', '', '', '', '10001', '10', $agreed, '', '', '', '', '');

将数据写入该循环中的缓冲区(最简单的选项)或将每一行追加到数组中(这是您实际尝试做的事情)。要附加它,你想要这样的东西:

$data[] = array($info[$i][1], $info[$i][2], 'GBP', '', '', $info[$i][3], '', $info[$i][4], $info[$i][5], $info[$i][6], 'GB', '', $info[$i][8], '', '', $info[$i][7], '', '', '', '', '', '', '', '', '', '10001', '10', $agreed, '', '', '', '', '');
//   ^ this is the change that makes it work

更多解释

$data是一个数组,但这并不会让它变得神奇。如果您为其指定了某些内容,例如$data = array(...);,则会替换其中的内容。你无法获得这些信息。

这意味着代码的结尾没有任何意义,特别是这篇文章(我已经格式化以使其可读):

// output each row of the data
for ($i = 0; $i < count($info); $i++) {
    foreach (array($data) as $row2){
        fputcsv($file, $row2);
    }
}

您尝试循环两次,一次基于MySQL结果中的行数,一次(内循环)基于$data中的内容。但是,由于您只在$data中存储了一行,因此内部循环无法工作。而且你真的只需要内循环(foreach);如果您实际将所有行保存到$data,则外部循环不会添加任何内容。

其他几点

此代码中还有许多其他主要问题。

  • don't use mysql_*; mysql_*函数已过时,deprecated和不安全 - 它们已完全从现代版本的PHP(7.0及更高版本)中删除。请改用MySQLiPDO
  • 永远不要使用for(...; $variable < count(something); ...)。*每次循环执行时都需要count()运行。这对于表演来说是一种杀气。有关此类事情有多糟糕的例子,请参阅phpbench.com
  • 正如Syscall指出的那样,您正与=中的if ($info[$i][10] = "yes")进行比较。这应该是==甚至是===
  • array()中的foreach (array($data) as $row2)...包装器是不必要的,实际上会导致问题。 (Syscall也指出。)把它拿出来。
  • 请格式化您的代码。用你写的方式来阅读它是非常困难的,这将使它保持非常不愉快。

* 如果something可以改变循环中的大小,那么这里有一个例外。但在这种情况下,对于你正在做的事情,可能比简单的for循环更好的设计。无论如何,你不会在这里做任何事情。

答案 1 :(得分:2)

  1. 要进行比较,您必须使用两个等号($info[$i][10] = "yes"应为$info[$i][10] == "yes")。
  2. 您必须使用$data将新数组附加到[]
  3. 在foreach循环中,您不必使用array($data),而是直接使用$data,并删除for循环:
  4. while ($row = mysql_fetch_array($result, MYSQL_NUM)) {$info[] = $row;}
    for ($i = 0; $i < count($info); $i++) {
        // compare using ==, not =
        if ($info[$i][10] == "yes") {$agreed = 'Agreement';}
        // append using [],
        $data[] = array($info[$i][1], $info[$i][2], 'GBP', '', '', $info[$i][3], '', $info[$i][4], $info[$i][5], $info[$i][6], 'GB', '', $info[$i][8], '', '', $info[$i][7], '', '', '', '', '', '', '', '', '', '10001', '10', $agreed, '', '', '', '', '');
    }
    // only one foreach, using $data, not array($data)
    foreach ($data as $row2) { fputcsv($file, $row2); }
    

    但是,我认为在while循环中创建CSV文件可能要容易得多,而不是创建3个循环:

    // use `$info` here
    while ($info = mysql_fetch_array($result, MYSQL_NUM)) {
        // compare using ==, not =
        if ($info[$i][10] == "yes") {$agreed = 'Agreement';}
        // create the CSV line,
        $data = array($info[$i][1], $info[$i][2], 'GBP', '', '', $info[$i][3], '', $info[$i][4], $info[$i][5], $info[$i][6], 'GB', '', $info[$i][8], '', '', $info[$i][7], '', '', '', '', '', '', '', '', '', '10001', '10', $agreed, '', '', '', '', '');
        // write it,
        fputcsv($file, $data);
    }