kubinyete/edi-php

一个用于读取 EDI 文件和声明您自己的 EDI 解析器的标准库

1.0.9 2024-05-03 12:33 UTC

This package is auto-updated.

Last update: 2024-09-03 13:42:40 UTC


README

声明 EDI 解析器的标准库,因为这不是一件有趣的事情。

为什么我应该使用它?

对于许多使用定义文本文件布局输出数据的服务的使用场景来说,这是一个非常常见的场景,例如,许多服务(例如:支付提供者)输出某种布局文件,该文件遵循简化列分隔值,并设置了固定的大小。

例如,以下行(25字节)

120240503Hello World

可以解释为

如何工作

为了在创建这些解析器时提供更好的开发人员体验,这个库提供了一些有用的属性属性和声明这些类型数据的基础类。

例如,要声明前面的行,我们可以在代码中声明如下

final class ExampleLayoutType extends Registry {
    #[Number(1)]
    public int $type;

    #[Date(8, format: '!Ymd')]
    public DateTimeInterface $type;

    #[Text(16)]
    public string $message;
}

// We can parse the data directly
$example = ExampleLayoutType::from('120240503Hello World     ')

// Or we can hydrate it
$example = new ExampleLayoutType();
$example->hydrate('120240503Hello World     ');

声明动态解析器

使用我们内置的行解析器,我们可以创建动态解析(按行)的类型,利用生成器的力量,这些类型是按需解析的

// Using a standard line parser, iterates over each line
class EDIParser extends LineParser
{
    // Ran on each line iteration
    protected function parse(LineContext $ctx): ?Registry
    {
        [$contents, $number] = $ctx->unwrap();
        // For this EDI file, we can deduce which type it is based on
        // the first 2 letters provided each line.
        $code = substr($contents, 0, 2);

        try {
            return match ($code) {
                EDIRegistry::TYPE_HEADER_START => EDIHeader::from($contents),
                EDIRegistry::TYPE_TRANSACTION_BATCH_START => EDITransactionBatch::from($contents),
                EDIRegistry::TYPE_SALE_RECEIPT => EDISaleReceipt::from($contents),
                // Our LineContext can provide a more verbose message to inform
                // where in our data the error ocurred.
                default => $ctx->raise("Cannot parse EDI of type '$code'", 0),
            };
        } catch (FieldException $e) {
            $ctx->raise($e->getMessage(), $e->getCursor());
        }
    }
}

// Using our parser directly
// Reading directly from stdin
$buffer = Stream::file('php://stdin', 'rb');
$parser = EDIParser::loadFromStream($buffer);

foreach ($parser as $registry) {
    /** @var Registry $registry */
    // We have direct access to our parsed objects on demand
    dump($registry);
}

理解解析错误

此功能正在开发中,我们可以做一些事情来使其更好

我们启用了对任何发生错误时友好上下文消息的内置支持。

PHP Fatal error:  Uncaught Kubinyete\Edi\Parser\Exception\ParseException: Line 1: Failed to parse field '202d1001025840' as a date with format 'YmdHis'
Contents: "A00003.1202d1001025840000442ADIQ SOLUCOES PAGAMENTOS S.A  0040002783189N000001"
           --------^
 in /home/vitorkubinyete/code/edi-php/src/Parser/LineContext.php:38