Hướng dẫn dùng contenttype csv trong PHP

  • Định Nghĩa.
  • Cú pháp.
    • Cú pháp:
    • Trong đó.
    • Giá trị trả về.
  • Sự thay đổi.
  • Ví dụ.
    • Ví dụ # 1 Sử dụng fpassthru () với các tệp nhị phân
      • code:
  • Ghi chú.
  • Hàm liên quan.
  • Thông tin thêm.

Nội dung chính

  • Định Nghĩa.
  • Trong đó.
  • Giá trị trả về.
  • Sự thay đổi.
  • Ví dụ # 1 Sử dụng fpassthru () với các tệp nhị phân
  • Hàm liên quan.
  • Thông tin thêm.
  • Định Nghĩa.
  • Trong đó.
  • Giá trị trả về.
  • Sự thay đổi.
  • Ví dụ # 1 Sử dụng fpassthru () với các tệp nhị phân
  • Hàm liên quan.
  • Thông tin thêm.
  • I. Trường hợp lỗi.
  • II. Sửa lỗi

Định Nghĩa.

Hàm fputcsv() định dạng một dòng là CSV và ghi nó vào một tệp đang mở.

Cú pháp.

Cú pháp:

fputcsv(file, fields, separator, enclosure, escape)

Trong đó.

Tham sốMô tả
file Chỉ định tệp đang mở để ghi vào
fields Chỉ định mảng nào để lấy dữ liệu từ
separator Một ký tự chỉ định dấu phân cách trường. Mặc định là dấu phẩy (,)
enclosure Một ký tự chỉ định ký tự bao vây trường. Mặc định là “
escape Chỉ định ký tự thoát. Mặc định là “\\”. Cũng có thể là một chuỗi rỗng (“”) vô hiệu hóa cơ chế thoát
  • Lưu ý: Nếu một ký tự bao vây được chứa trong một trường, nó sẽ được thoát bằng cách nhân đôi nó, trừ khi nó được đặt ngay trước một esc_char.

Giá trị trả về.

  • Trả về độ dài của chuỗi được viết hoặc FALSE khi thất bại.

Sự thay đổi.

  • PHP 7.4 – Tham số thoát bây giờ chấp nhận một chuỗi rỗng để vô hiệu hóa cơ chế thoát
  • PHP 5.5 – Đã thêm tham số escape

Ví dụ.

Ví dụ # 1 Sử dụng fpassthru () với các tệp nhị phân

code:

?php

$list = array (
    array('aaa', 'bbb', 'ccc', 'dddd'),
    array('123', '456', '789'),
    array('"aaa"', '"bbb"')
);

$fp = fopen('file.csv', 'w');

foreach ($list as $fields) {
    fputcsv($fp, $fields);
}

fclose($fp);
?>

Ví dụ trên sẽ ghi như sau vào file.csv:

aaa,bbb,ccc,dddd
123,456,789
"""aaa""","""bbb"""

Ghi chú.

  • Nếu PHP không nhận dạng chính xác các kết thúc dòng khi đọc tệp trên hoặc được tạo bởi máy tính Macintosh, thì bật tùy chọn cấu hình thời gian chạy auto_detect_line_endings có thể giúp giải quyết vấn đề.

Hàm liên quan.

  • fgetcsv() – Lấy dòng từ con trỏ tệp và phân tích cú pháp cho các trường CSV

Thông tin thêm.

  • Nếu bạn cần gửi tệp CSV trực tiếp đến trình duyệt, mà không cần ghi vào tệp bên ngoài, bạn có thể mở đầu ra và sử dụng fputcsv trên nó ..
  • Nếu bạn cần lưu đầu ra vào một biến (ví dụ: để sử dụng trong một framework), bạn có thể ghi vào trình bao bọc bộ nhớ tạm thời và truy xuất nội dung của nó:
    $csv fopen('php://temp/maxmemory:'. (5*1024*1024), 'r+');fputcsv($csv, array('blah','blah'));rewind($csv);$output stream_get_contents($csv);
    ?>
  • nếu bạn muốn tạo tệp UTF-8 cho excel, hãy sử dụng tệp này:
    $fp = fopen($filename, 'w');
    //add BOM to fix UTF-8 in Excel
    fputs($fp, $bom =( chr(0xEF) . chr(0xBB) . chr(0xBF) ));
  • Đôi khi thật hữu ích khi lấy dòng CSV dưới dạng chuỗi. I E. để lưu trữ nó ở đâu đó, không phải trên một hệ thống tập tin.

Các bạn có thể xem chi tiết hơn trên php.net.

Hi vọng với bài viết này, bạn đã hiểu rõ ứng dụng của hàm fputcsv() trong PHP. Nếu bạn thấy bài viết hay và có ý nghĩa hãy like và chia sẻ bài viết này để mọi người cùng nhau học tập nhé. Cảm ơn các bạn đã ghé thăm codetutam.com

  • Định Nghĩa.
  • Cú pháp.
    • Cú pháp:
    • Trong đó.
    • Giá trị trả về.
  • Sự thay đổi.
  • Ví dụ.
    • Ví dụ # 1 Sử dụng fpassthru () với các tệp nhị phân
      • code:
  • Ghi chú.
  • Hàm liên quan.
  • Thông tin thêm.

Nội dung chính

  • Định Nghĩa.
  • Trong đó.
  • Giá trị trả về.
  • Sự thay đổi.
  • Ví dụ # 1 Sử dụng fpassthru () với các tệp nhị phân
  • Hàm liên quan.
  • Thông tin thêm.
  • I. Trường hợp lỗi.
  • II. Sửa lỗi

Định Nghĩa.

Hàm fputcsv() định dạng một dòng là CSV và ghi nó vào một tệp đang mở.

Cú pháp.

Cú pháp:

fputcsv(file, fields, separator, enclosure, escape)

Trong đó.

Tham sốMô tả
file Chỉ định tệp đang mở để ghi vào
fields Chỉ định mảng nào để lấy dữ liệu từ
separator Một ký tự chỉ định dấu phân cách trường. Mặc định là dấu phẩy (,)
enclosure Một ký tự chỉ định ký tự bao vây trường. Mặc định là “
escape Chỉ định ký tự thoát. Mặc định là “\\”. Cũng có thể là một chuỗi rỗng (“”) vô hiệu hóa cơ chế thoát
  • Lưu ý: Nếu một ký tự bao vây được chứa trong một trường, nó sẽ được thoát bằng cách nhân đôi nó, trừ khi nó được đặt ngay trước một esc_char.

Giá trị trả về.

  • Trả về độ dài của chuỗi được viết hoặc FALSE khi thất bại.

Sự thay đổi.

  • PHP 7.4 – Tham số thoát bây giờ chấp nhận một chuỗi rỗng để vô hiệu hóa cơ chế thoát
  • PHP 5.5 – Đã thêm tham số escape

Ví dụ.

Ví dụ # 1 Sử dụng fpassthru () với các tệp nhị phân

code:

?php

$list = array (
    array('aaa', 'bbb', 'ccc', 'dddd'),
    array('123', '456', '789'),
    array('"aaa"', '"bbb"')
);

$fp = fopen('file.csv', 'w');

foreach ($list as $fields) {
    fputcsv($fp, $fields);
}

fclose($fp);
?>

Ví dụ trên sẽ ghi như sau vào file.csv:

aaa,bbb,ccc,dddd
123,456,789
"""aaa""","""bbb"""

Ghi chú.

  • Nếu PHP không nhận dạng chính xác các kết thúc dòng khi đọc tệp trên hoặc được tạo bởi máy tính Macintosh, thì bật tùy chọn cấu hình thời gian chạy auto_detect_line_endings có thể giúp giải quyết vấn đề.

Hàm liên quan.

  • fgetcsv() – Lấy dòng từ con trỏ tệp và phân tích cú pháp cho các trường CSV

Thông tin thêm.

  • Nếu bạn cần gửi tệp CSV trực tiếp đến trình duyệt, mà không cần ghi vào tệp bên ngoài, bạn có thể mở đầu ra và sử dụng fputcsv trên nó ..
  • Nếu bạn cần lưu đầu ra vào một biến (ví dụ: để sử dụng trong một framework), bạn có thể ghi vào trình bao bọc bộ nhớ tạm thời và truy xuất nội dung của nó:
    $csv fopen('php://temp/maxmemory:'. (5*1024*1024), 'r+');fputcsv($csv, array('blah','blah'));rewind($csv);$output stream_get_contents($csv);
    ?>
  • nếu bạn muốn tạo tệp UTF-8 cho excel, hãy sử dụng tệp này:
    $fp = fopen($filename, 'w');
    //add BOM to fix UTF-8 in Excel
    fputs($fp, $bom =( chr(0xEF) . chr(0xBB) . chr(0xBF) ));
  • Đôi khi thật hữu ích khi lấy dòng CSV dưới dạng chuỗi. I E. để lưu trữ nó ở đâu đó, không phải trên một hệ thống tập tin.

Các bạn có thể xem chi tiết hơn trên php.net.

Hi vọng với bài viết này, bạn đã hiểu rõ ứng dụng của hàm fputcsv() trong PHP. Nếu bạn thấy bài viết hay và có ý nghĩa hãy like và chia sẻ bài viết này để mọi người cùng nhau học tập nhé. Cảm ơn các bạn đã ghé thăm codetutam.com

Trong công việc và các dự án liên quan đến việc quản lý, chúng ta thường sẽ cần chức năng xuất và nhập dữ liệu từ file CSV. Đối với đa số các Framework PHP trên thị trường hiện nay thì việc này đều được hỗ trợ sẵn thông qua các thư viện được xây dựng sẵn.

Tuy nhiên trong vài trường hợp đối với các dữ liệu sử dụng ngôn ngữ tiếng Nhật hay tiếng Trung, đôi khi sẽ xảy ra trường hợp file được export ra sẽ không thể import vào đúng như ban đầu. Ví dụ dưới đây sẽ minh họa cho điều đó (Lưu ý: Framework sử dụng trong bài viết là FuelPHP).

I. Trường hợp lỗi.

Hàm Export Data ra file CSV

function get_export($shop_id)
{
   $shifts = \Util_Csv_Shift_Export::getShiftCsvData(); // Lay du lieu de export
   $csv_header = array('日付', 'パターン', '勤務開始時刻', '勤務終了時刻', '休憩開始時刻', '休憩終了時刻', 'グループ', 'スタッフ社員番号', 'スタッフ氏名');
   //download
   $response = new \Response();
   $response->set_header('Content-Type', 'application/csv');
   $response->set_header('Content-Disposition', 'attachment; filename="export.csv"');
   echo \Format::forge($shifts)->to_csv(null, null, false, $csv_header);
   return $response->send(true);
}

Hàm Import đọc dữ liệu từ file CSV.

public static function getDataTrimFile($file_path) {
    $row = 1;
    $data_file_trim = array();
    if (($handle = fopen($file_path, "r")) !== FALSE && \Util::check_file_encode($file_path)) {
        while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
            $new_data = array();
            foreach ($data as $value) {
                $new_data[] = mb_convert_encoding($value, "UTF-8", "cp932");
            }
            \Log::debug("Data: " + \Format::forge())
            $data_file_trim[$row] = $new_data;
            $row++;
        }
    }
    fclose($handle);
    return $data_file_trim;
}

Với hàm export như trên, chúng ta sẽ có được file dữ liệu như sau.

Chúng ta có thể thấy dữ liệu được export ra sẽ có 9 cột. Tiếp theo, chúng ta sẽ dùng chính file vừa rồi để import trở lại

Khi check file log của hệ thống, ta sẽ thấy

Có thể thấy là dữ liệu đọc vào từ file CSV này chỉ đọc được 8 cột ( Trong khi lúc Export chúng ta thấy có 9 cột). Nếu nhìn kỹ hơn trong vùng khoanh tròn thì có thể thấy 2 cột đã bị dính liền nhau khi đọc dữ liệu vào, ký tự “\u0022” là biểu tượng dấu ngoặc kép đã bị dính liền vào cột trước, do đó khi đọc file thì cột sau bị dính liền vào cột trước, làm dữ liệu  đọc vào bị thiếu mất 1 cột.

Khi xem kỹ hơn file được xuất ra, ta sẽ thấy.

Cột bên phải là file gốc, cột bên trái là file đã được mở bằng Microsoft Excel và được định dạng lại. Có thể dễ dàng nhận thấy là file bên trái khi được excel định dạng lại đã bỏ hết các dấu ngoặc kép phân cách giữa các từ, chỉ còn dấu phẩy ngăn cách. Vì vậy khi đọc file gốc, chương trình đã đọc luôn dấu ngoặc kép gây nên tình trạng đọc thiếu cột.

Khi sử dụng file đã được sửa bằng excel, chương trình sẽ chạy bình thường.

Có thể thấy là dữ liệu sau khi được chỉnh sửa định dạng bằng file Excel đã trở về đúng với tình trạng ban đầu. Để giải quyết tình trạng này, chúng ta sẽ thay đổi một chút về hàm xuất file CSV.

II. Sửa lỗi

Để xử lý lỗi trên, mình dùng cách tự convert từng dòng dữ liệu và sau đó put từng dòng vào file CSV. Khi đó dữ liệu sẽ được loại bỏ dấu ngoặc kép giữa các từ.

function get_export($shop_id)
{
    $shifts = \Util_Csv_Shift_Export::getShiftCsvData();
    $file_name = "shift_" . $shop_id . "_" . date('Ymd', strtotime($from_date)) . "_" . date('Ymd', strtotime($to_date));
    $csv_header = array('日付', 'パターン', '勤務開始時刻', '勤務終了時刻', '休憩開始時刻', '休憩終了時刻', 'グループ', 'スタッフ社員番号', 'スタッフ氏名');
    //download
    $response = new \Response();
    $response->set_header('Content-Type', 'octet-stream; charset:SJIS-win');
    $response->set_header('Content-Disposition', 'attachment; filename="test.csv"');
    $stream = fopen('php://output', 'w');
    $convert_header = self::convertToCSVData($csv_header);
    fputs($stream, $convert_header . "\n");
    $temp_array = array();
    foreach ($shifts as $shift) {         
        $converted_data = self::convertToCSVData($shift);
        fputs($stream, $converted_data . "\n");
    }
    return $response->send(true);
}
private static function convertToCSVData($data) {
    $csv_data = implode(',', $data);
    return mb_convert_encoding($csv_data, 'CP932', 'ASCII,JIS,UTF-8,eucJP-win,SJIS-win');    
}
  • Hàm **convertToCSVData **sẽ thay đổi dịnh dạng của dữ liệu từ các định dạng như ASCII, JIS, UTF-8, eucJP-win, SJIS-win về định dạng “CP932”.
  • Dữ liệu sau khi convert sẽ được put từng dòng vào file bằng hàm fputs

Đây là dữ liệu so sánh sau khi đã thay đổi hàm xuất file.

Có thể thấy bây h dữ liệu 2 file đã tương đồng nhau, do đó khi thực hiện việc import cũng sẽ ko còn gặp trường hợp lỗi như trên.