1

例如:csv有两列。结构是:它只有标题。

sku name

现在,有一个 foreach 循环:

foreach ($collection as $product_all) 
{
    $sku = $product_all['sku'];
    $product_id = Mage::getModel('catalog/product')->getIdBySku($sku);
    $product    = Mage::getModel('catalog/product');
    $product ->load($product_id);
    $name = $product['name'];
}

如果有 8000 行,我想将$sku和放入 csv 文件中。$name我该怎么办?我使用以下代码。但它不起作用。如何纠正它?谢谢你。

foreach ($collection as $product_all) 
{
    $sku = $product_all['sku'];
    $product_id = Mage::getModel('catalog/product')->getIdBySku($sku);
    $product    = Mage::getModel('catalog/product');
    $product ->load($product_id);   
    $name = $product['name'];
    $newCsvData = array();
    if (($handle = fopen("test.csv", "r")) !== FALSE) 
    {
        while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) 
        {
            $data[0] = $sku;
            $data[2] = $name;
            $newCsvData[] = $data;
        }
        fclose($handle);
    }

    $handle = fopen('test.csv', 'w');
    foreach ($newCsvData as $line) 
    {
        fputcsv($handle, $line);
    }

    fclose($handle);
}
4

4 回答 4

2

没试过,但应该可以。

$csvData = array();
foreach ($collection as $product_all) {
  $sku = $product_all['sku'];
  $product_id = Mage::getModel('catalog/product')->getIdBySku($sku);
  $product    = Mage::getModel('catalog/product');
  $product ->load($product_id);   
  $name = $product['name'];

  $csvData[] = array($sku, $name);
}


$handle = fopen('test.csv', 'w');
fputcsv($handle, array('sku', 'name'));
foreach($csvData as $row) {
  fputcsv($handle, $row);
}
fclose($handle);

fputcsv函数会为您处理所有转义,如果您希望 csv 文件适用于任何输入,这可不是一件容易的事。

在阅读了对其他答案的一些评论后,您可以fputcsv在循环中移动调用:

$handle = fopen('test.csv', 'w');
fputcsv($handle, array('sku', 'name'));

foreach ($collection as $product_all) {
  $sku = $product_all['sku'];
  $product_id = Mage::getModel('catalog/product')->getIdBySku($sku);
  $product    = Mage::getModel('catalog/product');
  $product ->load($product_id);   
  $name = $product['name'];

  fputcsv($handle, array($sku, $name));
}

fclose($handle);
于 2013-01-11T14:49:30.513 回答
1

我能想到的最简单的解决方案:

// The filename to write to
$csvFile = 'theCSVfile.csv';
$csvRows = array();

foreach ($collection as $product_all) {
  $sku = $product_all['sku'];
  $product_id = Mage::getModel('catalog/product')->getIdBySku($sku);
  $product    = Mage::getModel('catalog/product');
  $product ->load($product_id);
  // Replacing quotation marks with CSV escaped ones
  $name = str_replace( '"' , '""' , $product['name'] );

  $csvRows[] = "{$sku},\"{$name}\"";
}

file_put_contents( $csvFile , implode( "\n" , $csvRows ) );

请记住,如果$name变量包含逗号或其他异常字符,这可能会产生无效的 CSV 语法。

正如Bogdan所指出的,这可能是内存密集型的,因为它涉及在对文件执行单次写入之前将所有行保存在 RAM 中。如果这是一个问题,或者您正在处理大量行,则以下代码将写入批处理成更小的块。

// The filename to write to
$csvFile = 'theCSVfile.csv';
// Rows per chunk
$csvChunk = 1000;

// Initialise the Array
$csvRows = array();
// Variable to check if first write performed
$firstWriteDone = false;

function writeChunk(){
  global $csvFile, $csvRows, $csvChunk, $firstWriteDone;

  if( count( $csvRows )==$csvChunk ){
    // Chunk Limit Reached - Write to disk
    file_put_contents(
      $csvFile ,
      ( !$firstWriteDone ? "\n" : '' ) . implode( "\n" , $csvRows ) ,
      ( !$firstWriteDone ? FILE_APPEND : 0 )
    );
    // Set the First Write Done flag
    $firstWriteDone = true;
    // Reset the Array
    $csvRows = array();
  }
}

foreach ($collection as $product_all) {
  $sku = $product_all['sku'];
  $product_id = Mage::getModel('catalog/product')->getIdBySku($sku);
  $product    = Mage::getModel('catalog/product');
  $product ->load($product_id);
  // Replacing quotation marks with CSV escaped ones
  $name = str_replace( '"' , '""' , $product['name'] );

  $csvRows[] = "{$sku},\"{$name}\"";

  if( count( $csvRows )==$csvChunk ){
    // Chunk Limit Reached - Write to disk
    writeChunk();
  }
}
if( count( $csvRows ) ){
  // Write the Last Chunk, even if not at the limit
  writeChunk();
}
于 2013-01-11T14:42:09.830 回答
0

在迭代产品集合时将行写入文件。

$fh = fopen('test.csv', 'w');

foreach ($collection as $product_all) {
    $sku = $product_all['sku'];
    $product_id = Mage::getModel('catalog/product')->getIdBySku($sku);
    $product    = Mage::getModel('catalog/product');
    $product ->load($product_id);   
    $name = $product['name'];

    fwrite($fh, "{$sku},{$name}\n");
}

fclose($fh);
于 2013-01-11T15:01:01.787 回答
0

你的代码搞砸了人......对于每个数据库条目..你阅读csv ..从中收集日期(没有?)并将其“写入”到csv ..

修复你的代码:

    $newCsvData = array();

    foreach ($collection as $product_all) { 
        $sku = $product_all['sku'];

        $product_id = Mage::getModel('catalog/product')->getIdBySku($sku);

        $product = Mage::getModel('catalog/product');

        $product->load($product_id);

        $name = $product['name'];

        //move BEFORE the foreach
        /*$newCsvData = array();*/

        //remove this ...
        /*if (($handle = fopen("test.csv", "r")) !== FALSE) {
            while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
                $data[0] = $sku;
                $data[2] = $name;
                $newCsvData[] = $data;
            }
            fclose($handle);
        }*/

        //move AFTER the foreach
        /*
        $handle = fopen('test.csv', 'w');

        foreach ($newCsvData as $line) {
            fputcsv($handle, $line);
        }

        fclose($handle);*/
    }

    $handle = fopen('test.csv', 'w');

    foreach ($newCsvData as $line) {
        fputcsv($handle, $line);
    }

    fclose($handle);

检查其他示例,它们可能更好,只是习惯于指出您的代码有什么问题。

于 2013-01-11T14:58:31.223 回答