PHPackages                             gffuma/verga - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [File &amp; Storage](/categories/file-storage)
4. /
5. gffuma/verga

ActiveLibrary[File &amp; Storage](/categories/file-storage)

gffuma/verga
============

Verga, a battle-tested CSV importer for PHP

v0.1.0(9y ago)2221MITPHPPHP &gt;=5.5.0

Since Sep 13Pushed 9y ago2 watchersCompare

[ Source](https://github.com/gffuma/verga)[ Packagist](https://packagist.org/packages/gffuma/verga)[ RSS](/packages/gffuma-verga/feed)WikiDiscussions master Synced 2mo ago

READMEChangelogDependencies (1)Versions (2)Used By (0)

[![Build Status](https://camo.githubusercontent.com/3ad91fafe012d454604e29d9a89abf536c4b406dccb99a0ce188ef33c9734d20/68747470733a2f2f7472617669732d63692e6f72672f676666756d612f76657267612e7376673f6272616e63683d6d6173746572)](https://travis-ci.org/gffuma/verga)

Verga
=====

[](#verga)

Verga, a battle-tested CSV importer for PHP

[![](https://raw.githubusercontent.com/gffuma/verga/master/verga.gif)](https://raw.githubusercontent.com/gffuma/verga/master/verga.gif)

Installation
------------

[](#installation)

```
composer require gffuma/verga

```

Usage
-----

[](#usage)

This code is the same of [example](examples/import.php).

```
use Verga\Verga;

/**
 * Make the csv importer.
 *
 */
$importer = Verga::importer([

    /**
     * Number of rows to skip.
     * Default: 0
     *
     */
    'skip' => 1,

    /**
     * String used to parse csv lines.
     * Default ';'
     *
     */
    'delimiter' => ';',

    /**
     * Columns configuration.
     *
     */
    'cols' => [

        /**
         * Configure each column.
         *
         */
        'email' => [

            /**
             * Map the csv column at index 1 with the `email` field.
             *
             */
            'col' => 1,

            /**
             * When set to true and there is no column index in current csv
             * line. The line fail and the error is reported.
             * Default: true
             *
             */
            'required' => false,

            /**
             * The default value of column when is not required.
             * Default: null
             *
             */
            'default' => 'nobody@mail.it',

            /**
             * You can map every column value with a callback.
             *
             */
            'map' => function (

                /**
                 * The value of column.
                 *
                 */
                $value,

                /**
                 * The data parsed up to here.
                 *
                 */
                $data,

                /**
                 * All the csv row parsed by delimiter.
                 *
                 */
                $row,

                /**
                 * The csv line number.
                 *
                 */
                $lineNumber,

                /**
                 * Original csv line.
                 *
                 */
                $line
            ) {
                return strtolower($value);
            },

            /**
             * You can also validate each column value.
             *
             */
            'validate' => function ($value /*, $data, $row, $lineNumber, $line*/ ) {
                if (! filter_var($value, FILTER_VALIDATE_EMAIL)) {
                    return Verga::error("The email {$value} is invalid!");
                }
            }
        ],

        /**
         * This is a shortcut for:
         *
         * 'name' => [
         *     'col' => 0
         * ],
         */
        'name' => 0,

        /**
         * Map column to nested array:
         *
         */
        'info' => Verga::combine([

            'role' => Verga::combine([

                'name' => 2,

                'level' => [

                    'col' => 3,

                    'required' => false,

                    'default' => 'newbie',
                ],
            ]),
        ]),

        /**
         * You can also provide a fixed value for a column.
         *
         */
        'message' => [
            'value' => 'Imported from csv at ' . date('Y-m-d H:i:s')
        ],
    ],

    /**
     * Validate the entire line when provided.
     *
     */
    'validate' => function ($data, $row, $lineNumber, $line) {
        if ($lineNumber === 2) {
            return Verga::error('Sorry but i hate the second line :)');
        }
    },

    /**
     * Map the entire line when provided.
     *
     */
    'map' => function ($data /*,$row, $lineNumber, $line*/ ) {
        return array_map(function ($value) {
            if (is_array($value)) {
                return $value;
            }
            return '~~~' . strtoupper($value) . '~~~';
        }, $data);
    },

    /**
     * The import callback.
     *
     */
    'import' => function ($data /*, $row, $lineNumber, $line*/ ) {
        return 'Just import my friend ' . $data['name'];
    }
]);

/**
 * Now the imported is built, you can import the csv from differente sources:
 * file, url or direct from a string.
 *
 * The $result is an instance of Verga\Result\Result
 *
 * This class contains all the information and util methods
 * to inspect the result of current import.
 */
$result = $importer->importFromFile(
    /**
     * Source value.
     *
     */
    'users.csv',

    /**
     * Should import runned?
     * When is set to false the csv lines are processed and parsed
     * but the import callback is not runned.
     * Useful if you want only show the possible results before run
     * the real import...
     * Default: true
     */
    true
);
//$result = $importer->importFromUrl('https://somewhere.com/users.csv');
//$result = $importer->importFromString($_POST['csv_to_parse']);

// You can also get the lines alredy filtered:
// $result->getValidLines()
// $result->getInvalidLines()
foreach ($result->getLines() as $line) {

    // Is the line valid?
    $line->isValid();

    // Is the line invalid?
    $line->isInvalid();

    // Is the line imported?
    // true when is a valid line the import callback was runned
    $line->isImported();

    // Line original line number of csv from 0 to N
    $line->getLineNumber();

    // Original csv line
    $line->getLine();

    // The row parsed
    $line->getRow();

    // The parsed data
    $line->getParsedData();

    // The imported data returned from import callback
    $line->getImportedLine();

    // The columns errors when line is invalid
    $line->getColumnsErrors();
    $line->hasColumnsErrors();

    // The line error when line is invalid
    $line->getLineError();
    $line->hasLineError();
}
```

Todo
----

[](#todo)

- Retrieve feature with cache
- Implement jsonSerialize  interface on results objects for better js integration
- More friendly validation API try to use  as rule engine
- A way to stop import and prevent wrong data to be imported

###  Health Score

24

—

LowBetter than 32% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity10

Limited adoption so far

Community9

Small or concentrated contributor base

Maturity48

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

3530d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/da38ce59e5bd67c52f88c780f7f2ef35c76c4a4023009ef588a929bdfe417521?d=identicon)[gffuma](/maintainers/gffuma)

---

Top Contributors

[![gffuma](https://avatars.githubusercontent.com/u/5680676?v=4)](https://github.com/gffuma "gffuma (15 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/gffuma-verga/health.svg)

```
[![Health](https://phpackages.com/badges/gffuma-verga/health.svg)](https://phpackages.com/packages/gffuma-verga)
```

###  Alternatives

[knplabs/gaufrette

PHP library that provides a filesystem abstraction layer

2.5k39.8M123](/packages/knplabs-gaufrette)[google/cloud-storage

Cloud Storage Client for PHP

34390.8M125](/packages/google-cloud-storage)[illuminate/filesystem

The Illuminate Filesystem package.

15261.6M2.6k](/packages/illuminate-filesystem)[superbalist/flysystem-google-storage

Flysystem adapter for Google Cloud Storage

26320.6M30](/packages/superbalist-flysystem-google-storage)[creocoder/yii2-flysystem

The flysystem extension for the Yii framework

2931.7M62](/packages/creocoder-yii2-flysystem)[flowjs/flow-php-server

PHP library for handling chunk uploads. Works with flow.js html5 file uploads.

2451.6M15](/packages/flowjs-flow-php-server)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
