PHP code example of husail / edi-sdk

1. Go to this page and download the library: Download husail/edi-sdk library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

husail / edi-sdk example snippets


use Husail\EdiSdk\Schema\FieldType;
use Husail\EdiSdk\Schema\FileLayout;
use Husail\EdiSdk\Schema\RecordLayout;
use Husail\EdiSdk\Schema\Sequence\Record;
use Husail\EdiSdk\Schema\Sequence\Group;

$header = RecordLayout::define('header')
    ->lineLength(50)
    ->addField(name: 'type',    pos: 1,  len: 1,  type: FieldType::ALPHA,   const: 'H')
    ->addField(name: 'company', pos: 2,  len: 20, type: FieldType::ALPHA)
    ->addField(name: 'date',    pos: 22, len: 8,  type: FieldType::NUMERIC)
    ->addField(name: 'filler',  pos: 30, len: 21, type: FieldType::ALPHA,   ieldType::ALPHA,   const: 'T')
    ->addField(name: 'total_records', pos: 2, len: 6,  type: FieldType::NUMERIC, cast: 'int')
    ->addField(name: 'total_amount',  pos: 8, len: 15, type: FieldType::NUMERIC, cast: 'float', decimalPlaces: 2)
    ->build();

$layout = FileLayout::define('my-edi')
    ->lineLength(50)
    ->lineEnding("\r\n")
    ->addRecord($header)
    ->addRecord($detail)
    ->addRecord($trailer)
    ->withSequence([
        Record::one($header),
        Record::many($detail),
        Record::one($trailer),
    ])
    ->build();

use Husail\EdiSdk\Drivers\YamlDriver;

$layout = (new YamlDriver())->load('/path/to/my-edi.yaml');

use Husail\EdiSdk\Drivers\JsonDriver;

$layout = (new JsonDriver())->load('/path/to/my-edi.json');

use Husail\EdiSdk\Edi;

// Write to string
$content = Edi::write($layout)
    ->add('header', [
        'company' => 'ACME LTDA',
        'date'    => '06052026',
    ])
    ->add('detail', [
        'invoice'  => 1001,
        'customer' => 'JOAO SILVA',
        'amount'   => 150.75,
    ])
    ->add('detail', [
        'invoice'  => 1002,
        'customer' => 'MARIA SOUZA',
        'amount'   => 89.90,
    ])
    ->add('trailer', [
        'total_records' => 4,
        'total_amount'  => 240.65,
    ])
    ->toString();

// Save to file
Edi::write($layout)->add(...)->toFile('/path/to/file.txt');

use Husail\EdiSdk\Edi;

$result = Edi::parse(file_get_contents('/path/to/file.txt'), $layout);

// Access a single record
$header = $result->first('header');
echo $header?->get('company'); // 'ACME LTDA          '
echo $header?->get('nonexistent', default: 'fallback'); // 'fallback'

// Access a collection of records
$details = $result->records('detail');
$details->count();
$details->first()?->get('amount');  // 150.75 (float, when cast: float is set)
$details->last()?->get('customer');
$details->nth(1)?->get('invoice');

// Filter
$highValue = $details->filter(fn ($r) => $r->get('amount') > 100);
$highValue->count(); // 1

// Iterate
$details->each(fn ($r) => process($r));

// Retrocompatibility — returns array of arrays
$details->toArray();
$result->toArray();

use Husail\EdiSdk\Edi;

$result = Edi::validate(file_get_contents('/path/to/file.txt'), $layout);

if ($result->passes()) {
    // file is valid
}

foreach ($result->errors() as $error) {
    echo "Line {$error->line} [{$error->record}] {$error->field}: {$error->message}";
}

$result->errorsForLine(3);
$result->errorsForRecord('detail');
$result->errorCount();

use Husail\EdiSdk\Schema\Sequence\Record;
use Husail\EdiSdk\Schema\Sequence\Group;

$layout = FileLayout::define('cnab-like')
    ->lineLength(240)
    ->addRecord($fileHeader)
    ->addRecord($batchHeader)
    ->addRecord($segmentA)
    ->addRecord($segmentB)
    ->addRecord($batchTrailer)
    ->addRecord($fileTrailer)
    ->withSequence([
        Record::one($fileHeader),

        Group::repeat(
            identifyBy: fn (string $line): ?string => match ($line[7]) {
                '1' => 'batch_header',
                '3' => 'detail',
                '5' => 'batch_trailer',
                default => null,
            },
            children: [
                Record::one($batchHeader),

                Group::ambiguous(
                    identifyBy: fn (string $line): ?string => match ($line[13]) {
                        'A' => 'segment_a',
                        'B' => 'segment_b',
                        default => null,
                    },
                    children: [
                        Record::many($segmentA),
                        Record::optional($segmentB),
                    ]
                ),

                Record::one($batchTrailer),
            ]
        ),

        Record::one($fileTrailer),
    ])
    ->build();

$record = RecordLayout::define('detail')
    ->lineLength(50)
    ->addField(...)
    ->addValidator(function (array $data): ?string {
        if ($data['amount'] === '000000000000000') {
            return 'amount cannot be zero';
        }

        return null;
    })
    ->build();

use Husail\EdiSdk\Contracts\LayoutDriverInterface;
use Husail\EdiSdk\Schema\FileLayout;
use Husail\EdiSdk\Schema\Mapping\ArrayLayoutMapper;

class XmlLayoutDriver implements LayoutDriverInterface
{
    private ArrayLayoutMapper $mapper;

    public function __construct()
    {
        $this->mapper = new ArrayLayoutMapper();
    }

    public function load(mixed $source): FileLayout
    {
        $data = $this->parseXml($source); // convert XML → normalized array
        return $this->mapper->map($data);
    }
}