我正在尝试将多个数组输出到带有预设标头的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();
答案 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
,则外部循环不会添加任何内容。
此代码中还有许多其他主要问题。
mysql_*
; mysql_*
函数已过时,deprecated和不安全 - 它们已完全从现代版本的PHP(7.0及更高版本)中删除。请改用MySQLi
或PDO
。for(...; $variable < count(something); ...)
。*每次循环执行时都需要count()
运行。这对于表演来说是一种杀气。有关此类事情有多糟糕的例子,请参阅phpbench.com。=
中的if ($info[$i][10] = "yes")
进行比较。这应该是==
甚至是===
。array()
中的foreach (array($data) as $row2)...
包装器是不必要的,实际上会导致问题。 (Syscall也指出。)把它拿出来。 * 如果something
可以改变循环中的大小,那么这里有一个例外。但在这种情况下,对于你正在做的事情,可能比简单的for
循环更好的设计。无论如何,你不会在这里做任何事情。
答案 1 :(得分:2)
$info[$i][10] = "yes"
应为$info[$i][10] == "yes"
)。$data
将新数组附加到[]
。array($data)
,而是直接使用$data
,并删除for
循环:
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);
}