Kotchasan Framework Documentation

Kotchasan Framework Documentation

Csv Class - CSV File Management

EN 05 Feb 2026 07:46

Csv Class - CSV File Management

The Csv class provides tools for importing and exporting CSV data within the Kotchasan Framework.

namespace

Kotchasan\Csv;

Features

The Csv class supports reading and writing CSV files with character encoding management and data validation.

Important Properties

private $charset;   // Character encoding
private $columns;   // Column data
private $datas;     // Imported data
private $keys;      // Columns for duplicate checking;

Core Methods

import()

Import CSV data

class ExampleClass {
    <?php
public static function import($csv, $columns, $keys = null, $charset = 'UTF-8'): array;
}

Parameters:

  • $csv - CSV file path
  • $columns - Column data array array('column1' => 'data type', 'column2' => 'data type')
  • $keys - Column names for duplicate checking (null = no checking)
  • $charset - File encoding (default UTF-8)

Returns: Array of imported data

Usage Examples:

use Kotchasan\Csv;

// Import member data
$columns = [
    'name' => 'string',
    'email' => 'string',
    'age' => 'int',
    'salary' => 'double',
    'phone' => 'number',
    'join_date' => 'date'
];

$data = Csv::import('/path/to/members.csv', $columns);

foreach ($data as $row) {
    echo "Name: {$row['name']}, Email: {$row['email']}, Age: {$row['age']}\n";
}

// Import data with duplicate checking by email
$keys = ['email']; // Check duplicates by email
$data = Csv::import('/path/to/members.csv', $columns, $keys);

// Import data from TIS-620 encoded file
$data = Csv::import('/path/to/thai_data.csv', $columns, null, 'TIS-620');

// Import product data
$productColumns = [
    'product_code' => 'en',        // English letters and numbers only
    'product_name' => 'string',
    'price' => 'float',
    'stock' => 'int',
    'created_date' => 'datetime'
];

$products = Csv::import('/path/to/products.csv', $productColumns, ['product_code']);

// Import daily sales data
$salesColumns = [
    'sale_date' => 'date',
    'amount' => 'double',
    'customer_id' => 'int',
    'sale_time' => 'time'
];

$sales = Csv::import('/path/to/daily_sales.csv', $salesColumns);

// Use custom functions for data processing
$customColumns = [
    'email' => function($value) {
        return filter_var(trim($value), FILTER_VALIDATE_EMAIL) ?: null;
    },
    'phone' => function($value) {
        return preg_replace('/[^0-9]/', '', $value);
    },
    'name' => function($value) {
        return ucwords(trim($value));
    }
];

$cleanData = Csv::import('/path/to/contacts.csv', $customColumns);

read()

Read a CSV file and process each row of data

public static function read(
    $file,
    $onRow,
    $headers = null,
    $charset = 'UTF-8',
    $onBeforeRead = null,
    $args = null
): void;

Parameters:

  • $file - CSV file path
  • $onRow - Callback function to execute for each row function($row, $args)
  • $headers - Array of expected headers (optional)
  • $charset - File encoding (default UTF-8)
  • $onBeforeRead - Callback function before reading data function($columns, $args) (optional)
  • $args - Additional data to pass to callbacks (optional)

Throws: Exception if errors occur

Usage Examples:

use Kotchasan\Database;

<?php
use Kotchasan\Csv;

// Read CSV file and display each row
Csv::read('/path/to/data.csv', function($row) {
    echo "Processing row: " . print_r($row, true);
});

// Read file with header validation
$expectedHeaders = ['name', 'email', 'phone'];
Csv::read('/path/to/contacts.csv', function($row) {
    // Save data to database
    $db = \Kotchasan\Database::create();
    $db->table('contacts')->insert($row);
}, $expectedHeaders);

// Large data import system with batching
$batchSize = 1000;
$batch = [];
$count = 0;

Csv::read('/path/to/large_file.csv', function($row) use (&$batch, &$count, $batchSize) {
    $batch[] = $row;
    $count++;

    if (count($batch) >= $batchSize) {
        // Save batch
        $db = \Kotchasan\Database::create();
        $db->table('large_table')->insert($batch);

        echo "Processed {$count} rows\n";
        $batch = []; // Reset batch
    }
});

// Save final batch
if (!empty($batch)) {
    $db = \Kotchasan\Database::create();
    $db->table('large_table')->insert($batch);
    echo "Processing completed. Total {$count} rows\n";
}

// Data validation and cleaning system
Csv::read('/path/to/user_data.csv', function($row) {
    $errors = [];

    // Validate email
    if (!filter_var($row['email'], FILTER_VALIDATE_EMAIL)) {
        $errors[] = "Invalid email: {$row['email']}";
    }

    // Validate phone
    if (!preg_match('/^[0-9]{10}$/', $row['phone'])) {
        $errors[] = "Invalid phone: {$row['phone']}";
    }

    if (empty($errors)) {
        // Valid data, save to database
        echo "Saving data: {$row['name']}\n";
    } else {
        // Invalid data, log errors
        error_log("Invalid data: " . implode(', ', $errors));
    }
});

send()

Generate and send a CSV file as download

public static function send(
    $file,
    $header,
    $datas,
    $charset = 'UTF-8',
    $bom = true
): void;

Parameters:

  • $file - File name (without extension)
  • $header - Array of header values
  • $datas - Array of data rows
  • $charset - File encoding (default UTF-8)
  • $bom - Include Byte Order Mark (default true)

Returns: void (sends file and exits)

Usage Examples:

use Kotchasan\Database;

<?php
use Kotchasan\Csv;

// Export member data
$headers = ['Name', 'Surname', 'Email', 'Phone'];
$memberData = [
    ['John', 'Doe', 'john@example.com', '0812345678'],
    ['Jane', 'Smith', 'jane@example.com', '0823456789'],
    ['Bob', 'Johnson', 'bob@example.com', '0834567890']
];

Csv::send('members', $headers, $memberData);

// Export data from database
$db = \Kotchasan\Database::create();
$users = $db->table('users')
    ->select('name', 'email', 'created_at')
    ->toArray();

$headers = ['Name', 'Email', 'Registration Date'];
$userData = [];

foreach ($users as $user) {
    $userData[] = [
        $user['name'],
        $user['email'],
        date('Y-m-d', strtotime($user['created_at']))
    ];
}

Csv::send('user_report', $headers, $userData);

// Export data as TIS-620 for Thai programs
Csv::send('thai_report', $headers, $userData, 'TIS-620');

// Export monthly sales data
function exportMonthlySales($year, $month) {
    $db = \Kotchasan\Database::create();
    $sales = $db->table('sales s')
        ->join('products p', 'p.id = s.product_id')
        ->select('p.name', 's.quantity', 's.price', 's.total', 's.sale_date')
        ->where('YEAR(s.sale_date)', $year)
        ->where('MONTH(s.sale_date)', $month)
        ->toArray();

    $headers = ['Product Name', 'Quantity', 'Unit Price', 'Total', 'Sale Date'];
    $salesData = [];

    foreach ($sales as $sale) {
        $salesData[] = [
            $sale['name'],
            $sale['quantity'],
            number_format($sale['price'], 2),
            number_format($sale['total'], 2),
            $sale['sale_date']
        ];
    }

    $filename = "sales_{$year}_{$month}";
    return Csv::send($filename, $headers, $salesData);
}

// Export user activity report
function exportUserActivity() {
    $db = \Kotchasan\Database::create();
    $activities = $db->table('user_logs ul')
        ->join('users u', 'u.id = ul.user_id')
        ->select('u.name', 'u.email', 'ul.action', 'ul.ip_address', 'ul.created_at')
        ->order('ul.created_at DESC')
        ->limit(10000)
        ->toArray();

    $headers = ['User Name', 'Email', 'Action', 'IP Address', 'Time'];
    $activityData = [];

    foreach ($activities as $activity) {
        $activityData[] = [
            $activity['name'],
            $activity['email'],
            $activity['action'],
            $activity['ip_address'],
            $activity['created_at']
        ];
    }

    return Csv::send('user_activity_log', $headers, $activityData);
}

Advanced Usage Examples

use Kotchasan\Csv;
use Kotchasan\Database;

// Comprehensive CSV management system
class CsvManager
{
    // Import users from CSV
    public static function importUsers($csvFile) {
        $columns = [
            'username' => 'en',
            'email' => function($value) {
                $email = trim($value);
                return filter_var($email, FILTER_VALIDATE_EMAIL) ? $email : null;
            },
            'name' => 'string',
            'phone' => 'number',
            'birthdate' => 'date',
            'salary' => 'double'
        ];

        $keys = ['username', 'email']; // No duplicate username or email

        try {
            $users = Csv::import($csvFile, $columns, $keys);

            $db = Kotchasan\Database::create();
            $imported = 0;
            $errors = [];

            foreach ($users as $user) {
                // Check required data
                if (empty($user['username']) || empty($user['email'])) {
                    $errors[] = "Missing data: " . json_encode($user);
                    continue;
                }

                // Check if already exists
                $exists = $db->table('users')
                    ->where('username', $user['username'])
                    ->orWhere('email', $user['email'])
                    ->first();

                if ($exists) {
                    $errors[] = "Duplicate user: {$user['username']} / {$user['email']}";
                    continue;
                }

                // Add additional data
                $user['password'] = password_hash('123456', PASSWORD_DEFAULT);
                $user['status'] = 1;
                $user['created_at'] = date('Y-m-d H:i:s');

                // Save to database
                $db->table('users')->insert($user);
                $imported++;
            }

            return [
                'success' => true,
                'imported' => $imported,
                'total' => count($users),
                'errors' => $errors
            ];

        } catch (Exception $e) {
            return [
                'success' => false,
                'message' => $e->getMessage()
            ];
        }
    }

    // Export sales report
    public static function exportSalesReport($startDate, $endDate) {
        $db = Kotchasan\Database::create();

        $sales = $db->table('sales s')
            ->join('products p', 'p.id = s.product_id')
            ->join('users u', 'u.id = s.user_id')
            ->select(
                's.id',
                'p.name as product_name',
                'p.code as product_code',
                'u.name as customer_name',
                's.quantity',
                's.unit_price',
                's.total_price',
                's.sale_date',
                's.status'
            )
            ->whereBetween('s.sale_date', [$startDate, $endDate])
            ->order('s.sale_date DESC')
            ->toArray();

        $headers = [
            'Sale ID',
            'Product Code',
            'Product Name',
            'Customer',
            'Quantity',
            'Unit Price',
            'Total',
            'Sale Date',
            'Status'
        ];

        $salesData = [];
        $totalAmount = 0;

        foreach ($sales as $sale) {
            $statusText = $sale['status'] == 1 ? 'Success' : 'Cancelled';

            $salesData[] = [
                $sale['id'],
                $sale['product_code'],
                $sale['product_name'],
                $sale['customer_name'],
                $sale['quantity'],
                number_format($sale['unit_price'], 2),
                number_format($sale['total_price'], 2),
                $sale['sale_date'],
                $statusText
            ];

            if ($sale['status'] == 1) {
                $totalAmount += $sale['total_price'];
            }
        }

        // Add summary row
        $salesData[] = ['', '', '', '', '', '', '', '', ''];
        $salesData[] = ['', '', '', 'Grand Total', '', '', number_format($totalAmount, 2), '', ''];

        $filename = "sales_report_{$startDate}_to_{$endDate}";
        return Csv::send($filename, $headers, $salesData);
    }

    // Import products
    public static function importProducts($csvFile) {
        $result = [
            'total' => 0,
            'imported' => 0,
            'updated' => 0,
            'errors' => []
        ];

        Csv::read($csvFile, function($row) use (&$result) {
            $result['total']++;

            try {
                $db = Kotchasan\Database::create();

                // Clean data
                $productData = [
                    'code' => trim($row['code'] ?? ''),
                    'name' => trim($row['name'] ?? ''),
                    'price' => (float)($row['price'] ?? 0),
                    'cost' => (float)($row['cost'] ?? 0),
                    'stock' => (int)($row['stock'] ?? 0),
                    'category_id' => (int)($row['category_id'] ?? 0),
                    'description' => trim($row['description'] ?? ''),
                    'updated_at' => date('Y-m-d H:i:s')
                ];

                // Check required data
                if (empty($productData['code']) || empty($productData['name'])) {
                    $result['errors'][] = "Missing data: product code or name missing";
                    return;
                }

                // Check if product exists
                $existing = $db->table('products')
                    ->where('code', $productData['code'])
                    ->first();

                if ($existing) {
                    // Update data
                    $db->table('products')
                        ->where('code', $productData['code'])
                        ->update($productData);
                    $result['updated']++;
                } else {
                    // Add new data
                    $productData['created_at'] = date('Y-m-d H:i:s');
                    $db->table('products')->insert($productData);
                    $result['imported']++;
                }

            } catch (Exception $e) {
                $result['errors'][] = "Line {$result['total']}: " . $e->getMessage();
            }
        });

        return $result;
    }

    // Export CSV template
    public static function exportTemplate($type) {
        $templates = [
            'users' => [
                'filename' => 'user_import_template',
                'headers' => ['username', 'email', 'name', 'phone', 'birthdate', 'salary'],
                'sample' => [
                    ['john_doe', 'john@example.com', 'John Doe', '0812345678', '1990-01-15', '50000'],
                    ['jane_smith', 'jane@example.com', 'Jane Smith', '0823456789', '1985-05-20', '45000']
                ]
            ],
            'products' => [
                'filename' => 'product_import_template',
                'headers' => ['code', 'name', 'price', 'cost', 'stock', 'category_id', 'description'],
                'sample' => [
                    ['P001', 'Product A', '100.00', '80.00', '50', '1', 'Product A Description'],
                    ['P002', 'Product B', '200.00', '150.00', '30', '2', 'Product B Description']
                ]
            ]
        ];

        if (!isset($templates[$type])) {
            return false;
        }

        $template = $templates[$type];
        return Csv::send(
            $template['filename'],
            $template['headers'],
            $template['sample']
        );
    }
}

// Controller system for CSV management
class CsvController extends \Kotchasan\Controller
{
    public function import() {
        if ($this->request->getMethod() === 'POST') {
            $uploadedFile = $this->request->getUploadedFile('csv_file');
            $type = $this->request->getParsedBodyParam('type');

            if ($uploadedFile && $uploadedFile->getError() === UPLOAD_ERR_OK) {
                $tempFile = $uploadedFile->getTempName();

                switch ($type) {
                    case 'users':
                        $result = CsvManager::importUsers($tempFile);
                        break;
                    case 'products':
                        $result = CsvManager::importProducts($tempFile);
                        break;
                    default:
                        $result = ['success' => false, 'message' => 'Invalid type'];
                }

                header('Content-Type: application/json');
                echo json_encode($result);
            }
        } else {
            // Show upload form
            include ROOT_PATH . 'modules/csv/views/import.php';
        }
    }

    public function export() {
        $type = $this->request->getQueryParam('type');
        $format = $this->request->getQueryParam('format', 'data');

        switch ($type) {
            case 'sales':
                $startDate = $this->request->getQueryParam('start_date');
                $endDate = $this->request->getQueryParam('end_date');
                CsvManager::exportSalesReport($startDate, $endDate);
                break;

            case 'users':
                if ($format === 'template') {
                    CsvManager::exportTemplate('users');
                } else {
                    // Export actual user data
                }
                break;

            case 'products':
                if ($format === 'template') {
                    CsvManager::exportTemplate('products');
                } else {
                    // Export actual product data
                }
                break;
        }
    }
}

Usage Notes

  1. Encoding: Supports UTF-8, TIS-620 and other character encodings
  2. Data Types: string, int, double, float, number, en, date, datetime, time
  3. Custom Functions: Can use callback functions for data processing
  4. BOM: Supports adding Byte Order Mark for UTF-8
  5. Large Data: Use read() for streaming processing

The Csv class is a powerful tool for CSV file management in the Kotchasan Framework, supporting various data import and export formats and suitable for web application usage.