PortPHP

repository·master·Indexed 43 days ago

https://github.com/portphp/portphp

A PHP-based workflow engine designed for managing data import and export processes. It provides a structured way to handle data movement via a StepAggregator, supporting various adapters for CSV, Doctrine, DBAL, PDO, Excel, XML, and Spreadsheets. The engine includes built-in value converters for date formatting and object extraction, as well as filters for incremental imports, offset limiting, and Symfony-based data validation.

Tokens
14.8K
Snippets
59
Records
67
Agent score
54%

What's inside PortPHP

  1. Merge data sources with OneToManyReader

    master

    The OneToManyReader allows you to nest data from a 'child' reader into a 'parent' reader based on matching keys. This is useful for associating items (like order items) with a parent record (like an order).

    Constructor Parameters:

    1. $parentReader: The primary reader.
    2. $childReader: The reader containing the nested data.
    3. $nestingKey: The key name under which the child data will be nested in the parent row (e.g., 'items').
    4. $primaryKey: The key in the parent data used for matching.
    5. $foreignKey (optional): The key in the child data used for matching. If omitted, the reader uses the same name as the $primaryKey.
    use Port\Csv\CsvReader;
    use Port\Reader\OneToManyReader;
    
    $orderReader = new CsvReader(new \SplFileObject("orders.csv"));
    $orderReader->setHeaderRowNumber(0);
    
    $orderItemReader = new CsvReader(new \SplFileObject("order_items.csv"));
    $orderItemReader->setHeaderRowNumber(0);
    
    $oneToManyReader = new OneToManyReader(
        $orderReader,
        $orderItemReader,
        'items',    // Nesting key
        'OrderId',  // Primary key
        'OrderId'   // Foreign key
    );
  2. How PortPHP components work together

    master

    PortPHP is built around four primary component types that can be used either standalone or structured into a cohesive workflow:

    • Readers: Used to read data from various sources (e.g., Excel, CSV, SQL, streams).
    • Writers: Used to write data to targets (e.g., databases, Excel, or CSV files).
    • Value converters: Used to transform and clean input data during the pipeline.
    • Workflows: A way to organize these components into reusable, structured import/export pipelines.
  3. Install PortPHP format packages (CSV, Excel, Spreadsheet)

    master

    In PortPHP 1.0, readers and writers for specific formats are moved into dedicated packages. Install the one you need via Composer:

    • CSV: composer require portphp/csv
    • Excel: composer require portphp/excel
    • Spreadsheet: composer require portphp/spreadsheet
    composer require portphp/csv
    composer require portphp/excel
    composer require portphp/spreadsheet
  4. Upgrade PHP requirements for portphp 2.0

    master

    When upgrading to portphp 2.0, ensure your environment meets the new minimum PHP version requirement. PHP 7.4 through 8.1 are no longer supported.

    # Minimum required PHP version
    php --version # Must be 8.2 or higher
  5. Export data to a CSV file

    master

    To export data (from an ArrayReader or other source) to a CSV file, use CsvWriter within a StepAggregator workflow. You can use ValueConverterStep to transform data (e.g., capitalizing strings) during the export process.

    1. Initialize the Reader: Provide your data source (e.g., ArrayReader).
    2. Configure the Writer: Instantiate CsvWriter and use setStream() to specify the output file handle.
    3. Apply Transformations: Use ValueConverterStep to modify specific fields using closures or converters.
    4. Execute: Call $workflow->process().
    <?php
    
    use Port\Csv\CsvWriter;
    use Port\Reader\ArrayReader;
    use Port\Steps\StepAggregator;
    use Port\Steps\Step\ValueConverterStep;
    
    // Your input data
    $reader = new ArrayReader(array(
        array(
            'first',        // This is for the CSV header
            'last',
            array(
                'first' => 'james',
                'last'  => 'Bond'
            ),
            array(
                'first' => 'hugo',
                'last'  => 'Drax'
            )
        )
    ));
    
    // Create the workflow from the reader
    $workflow = new StepAggregator($reader);
    
    // Add the writer to the workflow
    $writer = new CsvWriter();
    $writer->setStream(fopen('output.csv', 'w'));
    $workflow->addWriter($writer);
    
    // Fix capitalization using a value converter
    $valueConverterStep = new ValueConverterStep();
    $valueConverterStep->add('first', function ($value) {
        return ucfirst($value);
    });
    $workflow->addStep($valueConverterStep);
    
    // Process the workflow
    $workflow->process();
  6. Use ValidatorFilter to validate data

    master

    The ValidatorFilter validates data before it is saved to a database. It requires the Symfony Validator component.

    Setup

    Install the Symfony Validator component via composer:

    $ compose require symfony/validator

    Usage

    Manual Assertions

    You can manually add constraints to specific fields using the add() method:

    <?php
    
    use Port\Filter\ValidatorFilter;
    use Symfony\Component\Validator\Constraints as Assert;
    
    // $validator is a Symfony Validator instance
    $filter = new ValidatorFilter($validator);
    $filter->add('email', new Assert\Email());
    $filter->add('sku', new Assert\NotBlank());

    Using Metadata/Annotations

    If you use a Symfony validator pre-configured with metadata resources (like object annotations), you do not need to add assertions manually:

    <?php
    
    use Port\Filter\ValidatorFilter;
    
    // $container is your Symfony service container
    $validator = $container->get('validator'); 
    $filter = new ValidatorFilter($validator);

    Error Handling

    • Default behavior: The filter collects all violations and skips each invalid row.
    • Stop on failure: To stop processing immediately upon encountering an error, call $filter->throwExceptions(). This will throw a ValidationException containing the line number and the list of violations.
    <?php
    
    use Port\Filter\ValidatorFilter;
    use Symfony\Component\Validator\Constraints as Assert;
    
    $filter = new ValidatorFilter($validator);
    $filter->add('email', new Assert\Email());
    $filter->add('sku', new Assert\NotBlank());
    
    // To stop on the first failing row:
    $filter->throwExceptions();
  7. Install PortPHP via Composer

    master

    To install the latest stable version of PortPHP, run the following command in your project directory using Composer:

    composer require portphp/steps

    After installation, ensure you include the Composer autoloader in your PHP project to enable the library's classes:

    require_once 'vendor/autoload.php';
    $ composer require portphp/steps