Installation
composer require flow-php/etl-adapter-csv
Ensure flow-php/etl is also installed (required dependency).
Basic Usage
use Flow\ETL\Adapter\CSV\CSVAdapter;
use Flow\ETL\Reader\ReaderInterface;
// Create a CSV reader
$reader = new CSVAdapter();
$reader->setFilePath('/path/to/your/file.csv');
// Read rows
foreach ($reader as $row) {
print_r($row); // Each row is an associative array
}
First Use Case: Simple Data Import
$reader = new CSVAdapter();
$reader->setFilePath(storage_path('import/users.csv'));
$reader->setDelimiter(';'); // Custom delimiter if needed
foreach ($reader as $userData) {
User::create([
'name' => $userData['name'],
'email' => $userData['email'],
]);
}
CSVAdapter: Main adapter class for reading/writing CSV.CSVReader: For reading CSV files (extends ReaderInterface).CSVWriter: For writing CSV files (if needed).$reader = new CSVAdapter();
$reader->setFilePath('data.csv');
$reader->setHeaderRow(0); // Use first row as headers
foreach ($reader as $row) {
// $row['column_name'] instead of $row[0]
}
$reader = new CSVAdapter();
$reader->setFilePath('large_file.csv');
$reader->setChunkSize(1000); // Process 1000 rows at a time
foreach ($reader as $chunk) {
foreach ($chunk as $row) {
// Process row
}
}
use Flow\ETL\Writer\CSVWriter;
$writer = new CSVWriter();
$writer->setFilePath(storage_path('export/users.csv'));
$writer->setDelimiter(';');
$writer->writeHeader(['id', 'name', 'email']);
$writer->writeRow([1, 'John Doe', 'john@example.com']);
// Dispatch a job for each CSV row
$reader = new CSVAdapter();
$reader->setFilePath('data.csv');
foreach ($reader as $row) {
ProcessUser::dispatch($row);
}
$reader = new CSVAdapter();
$reader->setFilePath('data.csv');
$reader->setHeaderRow(0);
foreach ($reader as $row) {
$validated = validator()->validate([
'email' => $row['email'] ?? '',
'name' => $row['name'] ?? '',
], [
'email' => 'required|email',
'name' => 'required|string',
]);
// Proceed with valid data
}
// app/Providers/ETLServiceProvider.php
public function register()
{
$this->app->singleton(ReaderInterface::class, function ($app) {
$reader = new CSVAdapter();
$reader->setFilePath(config('etl.csv_path'));
return $reader;
});
}
// config/etl.php
'csv' => [
'delimiter' => ';',
'enclosure' => '"',
'escape' => '\\',
],
$reader = new CSVAdapter();
$reader->setDelimiter(config('etl.csv.delimiter'));
try {
$reader = new CSVAdapter();
$reader->setFilePath('missing.csv');
foreach ($reader as $row) {
// ...
}
} catch (\Flow\ETL\Exception\FileNotFoundException $e) {
Log::error('CSV file not found: ' . $e->getMessage());
}
Memory Issues with Large Files
setChunkSize() for large CSV files to avoid memory exhaustion.$reader->setChunkSize(500);Header Row Misconfiguration
setHeaderRow() is not set, the adapter assumes no headers, and columns are accessed numerically ($row[0], $row[1]).$reader->setHeaderRow(0); // First row is headers
Encoding Problems
setEncoding():
$reader->setEncoding('UTF-8');
Line Endings (\n vs \r\n)
$reader->setRawMode(true); // Access raw lines if needed
Empty or Malformed Rows
foreach ($reader as $row) {
if (empty(array_filter($row))) {
continue; // Skip empty rows
}
}
Inspect Raw Data
$reader = new CSVAdapter();
$reader->setFilePath('data.csv');
$reader->setRawMode(true); // Access raw lines
foreach ($reader as $rawLine) {
logger()->debug('Raw line: ' . $rawLine);
}
Validate CSV Structure
Log Adapter Configuration
$reader = new CSVAdapter();
$reader->setFilePath('data.csv');
$reader->setDelimiter(';');
$reader->setHeaderRow(0);
logger()->debug('CSV Adapter Config:', [
'delimiter' => $reader->getDelimiter(),
'header_row' => $reader->getHeaderRow(),
'encoding' => $reader->getEncoding(),
]);
Custom Row Processing
CSVAdapter to add preprocessing:
class CustomCSVAdapter extends CSVAdapter
{
public function processRow($row)
{
// Transform or validate row before yielding
return $this->transformRow($row);
}
protected function transformRow($row)
{
// Custom logic
$row['processed_at'] = now()->toDateTimeString();
return $row;
}
}
Custom Writers
CSVWriter to add features like:
Event Dispatching
$reader = new CSVAdapter();
$reader->setFilePath('data.csv');
$reader->on('row', function ($row) {
event(new CSVRowProcessed($row));
});
Integration with Laravel Events
// Listen for CSV row events
event(new CSVRowProcessed($row));
// In EventServiceProvider
protected $listen = [
CSVRowProcessed::class => [
HandleCSVRow::class,
],
];
Stream Large Files
$reader = new CSVAdapter();
$reader->setFilePath('huge_file.csv');
$reader->setStream(true); // Stream rows one by one
Disable Unused Features
Batch Database Inserts
DB::insert with batch inserts for better performance:
$batch = [];
foreach ($reader as $row) {
$batch[] = [
'name' => $row['name'],
'email' => $row['email'],
];
if (count($batch) >= 1000) {
DB::table('users')->insert($batch);
$batch = [];
}
}
// Insert remaining rows
if (!empty($batch)) {
DB::table('
How can I help you explore Laravel packages today?