Kotchasan Framework Documentation
Csv Class - CSV File Management
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 arrayarray('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 rowfunction($row, $args)$headers- Array of expected headers (optional)$charset- File encoding (default UTF-8)$onBeforeRead- Callback function before reading datafunction($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
- Encoding: Supports UTF-8, TIS-620 and other character encodings
- Data Types: string, int, double, float, number, en, date, datetime, time
- Custom Functions: Can use callback functions for data processing
- BOM: Supports adding Byte Order Mark for UTF-8
- 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.