【问题标题】:Generated CSV downloads empty but has content生成的 CSV 下载为空但有内容
【发布时间】:2014-09-22 11:18:19
【问题描述】:

我编写了以下脚本,该脚本用于根据数据库中的内容创建 CSV 文件。该脚本本身可以完美运行并创建 CSV 文件并按预期填充它。问题是当文件自动下载时它是空的,但是当通过 FTP 从托管服务器下载它时,它会充满信息。

在文件成功写入之前文件是否刚刚下载?有什么办法可以解决这个问题吗?

<?php

    // Establish the MySQL Database Connection
    include_once("./include/database.php");
    include("functions.php");

    $filename = 'devices.csv';
    $headers = array('ID', 'Device', 'Name', 'Type', 'Scope', 'OS', 'Datacenter');

    $handle = fopen($filename, 'w');
    fputcsv($handle, $headers, ',', '"');

    $sql = mysql_query("SELECT * FROM devices ORDER BY name ASC", $dp_conn);

    while($results = mysql_fetch_object($sql))
    {
        $type = getDeviceType($results->type, $dp_conn);
        $scope = getDeviceScope($results->scope, $dp_conn);
        $os = getOS($results->os, $dp_conn);
        $datacenter = getDatacenter($results->datacenter, $dp_conn);

        $row = array(
            $results->id,
            $results->device_id,
            $results->name,
            $type,
            $scope['name'],
            $os,
            $datacenter
        );

        fputcsv($handle, $row, ',', '"');
    }

    // rewind the "file" with the csv lines
    fseek($handle, 0);

    header('Content-Type: application/csv');
    header('Content-Disposition: attachment; filename="' . $filename . '";');

    // make php send the generated csv lines to the browser
    fpassthru($handle);

    fclose($handle);

?>

【问题讨论】:

    标签: php mysql csv download dynamically-generated


    【解决方案1】:

    在进一步测试并找到有关该主题的类似帖子后,我找到了解决方法。我没有在文件上使用 fopen(),而是将数据写入内存,现在它可以正常工作了。

    <?php
    
        // Establish the MySQL Database Connection
        include_once("./include/database.php");
        include("functions.php");
    
        $filename = 'devices.csv';
        $headers = array('ID', 'Device', 'Name', 'Type', 'Scope', 'OS', 'Datacenter');
    
        //$handle = fopen($filename, 'w');
        $handle = fopen('php://memory', 'w'); 
        fputcsv($handle, $headers, ',', '"');
    
        $sql = mysql_query("SELECT * FROM devices ORDER BY name ASC", $dp_conn);
    
        while($results = mysql_fetch_object($sql))
        {
            $type = getDeviceType($results->type, $dp_conn);
            $scope = getDeviceScope($results->scope, $dp_conn);
            $os = getOS($results->os, $dp_conn);
            $datacenter = getDatacenter($results->datacenter, $dp_conn);
    
            $row = array(
                $results->id,
                $results->device_id,
                $results->name,
                $type,
                $scope['name'],
                $os,
                $datacenter
            );
    
            fputcsv($handle, $row, ',', '"');
        }
    
        // rewind the "file" with the csv lines
        fseek($handle, 0);
    
        header('Content-Type: application/csv');
        header('Content-Disposition: attachment; filename="' . $filename . '";');
    
        // make php send the generated csv lines to the browser
        fpassthru($handle);
    
        fclose($handle);
    
    ?>
    

    【讨论】:

      【解决方案2】:

      试试这个

      // Establish the MySQL Database Connection
      include_once("./include/database.php");
      include("functions.php");
      
      ob_start(); //start output buffering 
      
      $filename = 'devices.csv';
      $headers = array('ID', 'Device', 'Name', 'Type', 'Scope', 'OS', 'Datacenter');
      
      $handle = fopen($filename, 'w');
      fputcsv($handle, $headers, ',', '"');
      
      $sql = mysql_query("SELECT * FROM devices ORDER BY name ASC", $dp_conn);
      
      while($results = mysql_fetch_object($sql))
      {
          $type = getDeviceType($results->type, $dp_conn);
          $scope = getDeviceScope($results->scope, $dp_conn);
          $os = getOS($results->os, $dp_conn);
          $datacenter = getDatacenter($results->datacenter, $dp_conn);
      
          $row = array(
              $results->id,
              $results->device_id,
              $results->name,
              $type,
              $scope['name'],
              $os,
              $datacenter
          );
      
          fputcsv($handle, $row, ',', '"');
      }
      
      ob_end_clean(); //ending output buffering. 
      
      // rewind the "file" with the csv lines
      fseek($handle, 0);
      
      header('Content-Type: application/csv');
      header('Content-Disposition: attachment; filename="' . $filename . '";');
      
      // make php send the generated csv lines to the browser
      fpassthru($handle);
      
      fclose($handle);
      

      【讨论】:

      • 这不起作用,因为 $handle 已关闭。警告:fpassthru(): 8 不是第 44 行 /home/devpo/public_html/device_csv.php 中的有效流资源
      • 这可能是输出缓冲的情况所以 ob_start();在你的while循环之前和你的while循环结束之后的ob_end_clean()......这会将所有更改推送到你的文件
      猜你喜欢
      • 2017-11-14
      • 2019-04-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-06
      • 1970-01-01
      • 1970-01-01
      • 2021-04-30
      相关资源
      最近更新 更多