Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Php Csv Parser Laravel Package

kzykhys/php-csv-parser

kzykhys/php-csv-parser is a lightweight PHP library for reading and parsing CSV files. It offers a simple API, iterator-based access, configurable delimiters and enclosures, and optional header handling for straightforward CSV import tasks.

View on GitHub
Deep Wiki
Context7

Getting Started

Install it as a plain Composer dependency — there is no Laravel service provider or facade to register:

composer require kzykhys/php-csv-parser

Then look first at the package README and vendor/kzykhys/php-csv-parser/src/KzykHys/CsvParser/CsvParser.php. The API is intentionally small: instantiate CsvParser and call parse() with a file path or CSV string. Confirm the exact string-input constant and option setters in the README for the installed version; the stable entry point is the parser instance plus parse().

use KzykHys\CsvParser\CsvParser;

$parser = new CsvParser();
$rows = $parser->parse(storage_path('app/private/imports/users.csv'));

// First row is not special to most CSV parsers; treat headers yourself:
$headers = array_shift($rows);

The first practical use case is a user-uploaded CSV import: validate the upload in a FormRequest, store it under storage/app/private/imports, parse it in a queued job, normalize the header row, validate each data row, and persist with Eloquent. For example:

$path = $request->file('csv')->store('imports');
ImportCsvJob::dispatch($path);

Because the package claims Excel-style support, it is most valuable when the input comes from Excel exports — BOMs, CRLF line endings, quoted commas, and multiline fields are the cases worth testing first.

Implementation Patterns

Wrap the parser in your own service so controllers and jobs do not depend directly on a 2014 utility class. Bind it once and inject the wrapper:

// AppServiceProvider
$this->app->singleton(CsvParser::class, fn () => new CsvParser());
class CsvImporter
{
    public function __construct(private CsvParser $parser) {}

    public function import(string $absolutePath): array
    {
        $rows = $this->parser->parse($absolutePath);
        $headers = array_map(
            fn ($h) => Str::slug(trim($h), '_'),
            array_shift($rows)
        );

        return [$headers, $rows];
    }
}

A typical queued import pattern:

class ImportCsvJob implements ShouldQueue
{
    public function __construct(public string $path) {}

    public function handle(CsvImporter $importer): void
    {
        [$headers, $rows] = $importer->import(Storage::path($this->path));

        $rules = ['email' => 'required|email', 'name' => 'required|string'];

        DB::transaction(function () use ($headers, $rows, $rules) {
            foreach ($rows as $index => $row) {
                if (count($row) !== count($headers)) {
                    // log or collect as row error
                    continue;
                }

                $data = array_combine($headers, $row);
                $validator = Validator::make($data, $rules);

                if ($validator->fails()) {
                    // collect errors keyed by $index + 2 (header is row 1)
                    continue;
                }

                User::updateOrCreate(
                    ['email' => $data['email']],
                    $data
                );
            }
        });
    }
}

Use updateOrCreate or upsert on a natural key so re-running an import is idempotent. Validate per row rather than trying to validate the whole file at once; include the CSV row number in error messages so users can fix the source file.

For Excel exports from locales that use semicolons, configure the delimiter if the installed version exposes setters or parse options. Do not rely on auto-detection for production imports — pass the delimiter, enclosure, escape, and encoding explicitly based on the source system.

Testing is straightforward with Storage::fake() and fixture files:

Storage::fake('local');
Storage::put('imports/users.csv', "email,name\[email protected],Jane\n");

If the package supports parsing from a string constant, use that in unit tests to avoid temp files; otherwise create fixtures under tests/Fixtures.

Also add an Artisan command around the same service (php artisan csv:import {path}) so imports can be re-run and debugged outside HTTP requests.

Gotchas and Tips

  • This is unmaintained. Last release was 2014, zero dependents on Packagist, and no Laravel integration. It may install on modern PHP because its constraint is permissive, but test on your PHP version before committing. For new projects, league/csv is the safer long-term choice. If you keep this package, isolate it behind your own CsvImporter interface so swapping later is a one-class change.
  • It returns the whole file as an array. That is fine for small uploads but dangerous for large CSVs. For files above a few thousand rows, use SplFileObject + fgetcsv() for streaming, or chunk at the job level. Do not parse a 100 MB upload synchronously in a web request.
  • Excel output is not always UTF-8. Excel frequently emits UTF-8 with BOM, Windows-1252, or Shift-JIS depending on locale. Strip the BOM from the first header (ltrim($header, "\xEF\xBB\xBF")) and convert encoding explicitly if needed. Test with real Excel files, not hand-written CSVs.
  • Delimiter assumptions break. European Excel often uses ;; tab-separated exports use \t. Configure explicitly. Also verify escape-character behavior across PHP versions — PHP has changed fgetcsv() escape handling in recent releases and can emit deprecation warnings.
  • Headers are yours to manage. The parser returns rows; it does not map column names or skip a header row for you. Normalize header names, guard against duplicate or missing columns, and check count($row) === count($headers) before array_combine() — PHP 8 throws a ValueError on mismatched lengths.
  • Empty lines and trailing newlines. CSV files often end with blank rows. Filter them, but be careful: a row of empty strings is not always the same as a blank line depending on how the parser represents it.
  • CSV injection on re-export. If you later export user-supplied data back to CSV, sanitize cells beginning with =, +, -, or @ to avoid formula injection in Excel.
  • No extension points. There are no events, interfaces, or custom readers. That is another reason to wrap it: your wrapper is the extension point, and it lets you add logging, row-error collection, and progress reporting without touching vendor code.
  • Debug with real malformed inputs. Keep fixtures for multiline quoted fields, embedded commas, CRLF, BOM, and mismatched column counts. Most CSV bugs show up in those five cases, not in clean test data.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin