2012-01-29 66 views
0

所以,我認爲我已經問了這個問題和其他相關的問題兩次以上。但我無法弄清楚發生了什麼。導出CSV |奇怪的行爲

我使用這個PHP函數將一些數據從表格導出到CSV表格。我測試本地主機上(XAAMP):

// Export CSV By User Level 
public function CSVData($path, $level) { 

    switch ($level) { 
     case 0: 
      $filename = $path."/standard_members_".date('Y')."_".date('m')."_".date('d').".csv"; 
      break; 
     case 1: 
      $filename = $path."/special_members_".date('Y')."_".date('m')."_".date('d').".csv"; 
      break; 
     case 2: 
      $filename = $path."/admin_members_".date('Y')."_".date('m')."_".date('d').".csv"; 
      break; 
     default: 
      break; 
    } 


    $sql = "SELECT user_name, user_username, user_email, user_register_date INTO OUTFILE '$filename' FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '\"' LINES TERMINATED BY '\n' FROM users WHERE user_level = '$level'"; 

    if ($stmt = $this->connect->prepare($sql)) {  
     if(!($stmt->execute())){ 
      print_r($stmt->error); 
     } 
     $stmt->close(); 
    } else { 
     $error    = true; 
     $message['error'] = true; 
     $message['message'] = CANNOT_PREPARE_DATABASE_CONNECTION_MESSAGE; 
     return json_encode($message); 
    } 


    if(!is_file($filename)) { 
     die('file not found'); 
    } else { 
     header('Content-Type: application/csv'); 
     header("Content-Disposition: attachment; filename=$filename"); 
     header('Expires: 0'); 
     header('Pragma: no-cache'); 
     readfile($filename); 
    } 

} 

而且我有一個執行的操作,我的意思是提交行動到處理上述功能的PHP文件,這是行動代碼的形式:

<?php 

    include '../assets/class/login/loginsys.php'; 

    $extension = new extension; 

    if ($_GET['action'] == 0) { 

     $extension->CSVData('exports', 0); 

    } elseif ($_GET['action'] == 1) { 

     $extension->CSVData('exports', 1); 

    } elseif ($_GET['action'] == 2) { 

    $extension->CSVData('exports', 2); 

    } 

    exit(); 

?> 

會發生什麼情況如下:

- 當我點擊提交表單上按鈕我有其發送或者值0,1或2的動作代碼; - 動作代碼獲取相應的值並進行處理; - 但如果我沒有創建本地主機上的文件夾「出口」,如果本來給了我這個錯誤:

Can't create/write to file 'C:xampphtdocsloginadminexports\standard_members_2012_01_28.csv' (Errcode: 2); 

- 和我創造了它,所以它可以工作; -現在創建了CSV文件所在的文件夾並將數據轉儲到CSV表中; - 但是在我的瀏覽器中打開的文件(下載的附件像你點擊某個網站上的文件並下載它)即使在'exports'中導出的文件中有數據,它也是空的; - 和另一件事是,當文件夾「出口」表已經存在時創建的告訴我:

File 'exports/admin_members_2012_01_29.csv' already exists 

所以我的問題是,爲什麼我是這麼描述發生了什麼?有沒有辦法讓MySql查詢覆蓋以前的CSV文件?

+0

This SO answer will help,http://stackoverflow.com/questions/960627/mysql-into-outfile-overide-existing-file你不能覆蓋輸出的文件,所以你需要命名文件唯一與microtime或在創建新備份之前將輸出的文件移動到別處.. – 2012-01-29 09:19:53

+0

投票將其視爲「過於本地化」,但以下是一些提示,供您考慮:您是如何追蹤此錯誤的?你有什麼選擇考慮和測試?你在哪裏輸出文件到瀏覽器?你是否像MySQL一樣從文件夾中讀取文件?爲什麼不在運行SQL查詢之前檢查文件是否存在? – 2012-01-29 09:19:58

+0

@EmilVikstrom - 我不知道該怎麼做來追蹤錯誤。您看到的代碼就是我測試過的代碼,它會按照描述導出文件,但瀏覽器下載的文件是空的。我將它輸出到我的硬盤上的一個文件夾中,一個單獨的分區,而不是我的操作系統所在的分區,但是其他文件的行爲與其假設的一樣(如果我從網站下載某些內容)。我不確定,但不,我正在閱讀下載的文件,但它不應該是空的嗎?我如何檢查文件的存在?我試過'if(!is_file($ filename)){unlink($ filename); }'但文件仍然存在。 – Roland 2012-01-29 09:40:23

回答

1

你不需要那個臨時文件。這個怎麼樣:

define('CSV_SEPARATOR', ','); 

// CSV download headers 
header('Content-Type: text/csv; charset=UTF-8'); 
header('Content-Disposition: attachment; filename="my.csv"'); 

// A file handle to PHP output stream 
$fp = fopen('php://output', 'w'); 

// UTF-8 BOM 
echo "\xEF\xBB\xBF"; 

// Get data from database 
$data = ...; 

// List of columns 
$columns = array(
    'User name', 
    'First name', 
    'Last name' 
); 

foreach ($data as $key => $row) { 

    // Write columns 
    if ($key == 0) { 
    fputcsv($fp, $columns, CSV_SEPARATOR); 
    } 

    // Write data 
    fputcsv($fp, $row, CSV_SEPARATOR); 
} 

fclose($fp); 

美麗,不是嗎?

+0

是的,我試過這種方法沒有成功,爲什麼不使用MySql查詢時更容易使用查詢而不是使用PHP。 – Roland 2012-01-29 09:42:26

+0

我不確定你的意思,代碼完美。並回答爲什麼:a)沒有臨時文件被創建,沒有留下任何東西,b)代碼是可移植的(沒有MySQL依賴) – Sim 2012-01-29 09:48:00

+0

那麼$數據是什麼?一個數組還是什麼? – Roland 2012-01-29 09:52:42