1. Go to this page and download the library: Download chemaclass/edifact-parser 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/ */
chemaclass / edifact-parser example snippets
declare(strict_types=1);
use EdifactParser\EdifactParser;
File('/path/to/order.edi'); // or ->parse($ediString)
foreach ($result->transactionMessages() as $message) {
echo $message->messageType(); // 'ORDERS', 'INVOIC', 'IFTMIN', …
// Typed accessors — no magic array indices
$buyer = $message->segmentByTagAndSubId('NAD', 'BY');
echo $buyer?->name(); // 'ACME Corporation'
echo $buyer?->countryCode(); // 'DE'
foreach ($message->lineItems() as $lineItem) {
$qty = $lineItem->segmentByTagAndSubId('QTY', '21');
echo $qty?->quantityAsFloat(); // 100.0
}
}
$result = EdifactParser::createWithDefaultSegments()->parse($ediString);
$result->transactionMessages(); // list<TransactionMessage> — the UNH…UNT blocks
$result->functionalGroups(); // list<FunctionalGroup> — UNG…UNE groups, if any
$result->globalSegments(); // TransactionMessage — file-level UNA/UNB/UNZ
$result->firstMessage(); // ?TransactionMessage
$result->messagesOfType('INVOIC'); // list<TransactionMessage> — an interchange may mix types
count($result); // number of messages
foreach ($result as $message) { … } // iterate the messages directly
use EdifactParser\Tokenizer\SabasTokenizer;
new EdifactParser(SegmentFactory::withDefaultSegments(), tokenizer: new SabasTokenizer());
use EdifactParser\StreamingParser;
foreach (StreamingParser::createWithDefaultSegments()->parseFile('/path/to/large.edi') as $message) {
process($message); // only one message is held in memory at a time
}
// NAD (Name & Address)
$nad->partyQualifier(); // 'BY'
$nad->name(); // 'ACME Corporation'
$nad->street();
$nad->city();
$nad->postalCode();
$nad->countryCode(); // ISO 3166-1 alpha-2
// QTY / PRI — with numeric conversion
$qty->quantityAsFloat(); // float
$qty->measureUnit(); // 'PCE', 'KGM', …
$pri->priceAsFloat(); // float
// DTM — with date parsing
$dtm->asDateTime(); // DateTimeImmutable|null
// Fastest single lookup, by tag + subId
$nad = $message->segmentByTagAndSubId('NAD', 'BY'); // ?SegmentInterface
// All segments with a tag (keyed by subId)
$allNad = $message->segmentsByTag('NAD');
$nad?->name(); // always null-check — not every segment exists in every message
// Presence and counts, answered from an index built once per message
$message->has('QTY'); // bool
$message->countByTag(); // ['UNH' => 1, 'NAD' => 2, 'LIN' => 40, …]
count($message); // total segments, duplicates
foreach ($message->lineItems() as $lineItem) {
$lin = $lineItem->segmentByTagAndSubId('LIN', '1');
$qty = $lineItem->segmentByTagAndSubId('QTY', '21');
echo $lin?->itemNumber(); // product identifier
echo $qty?->quantityAsFloat();
count($lineItem); // segments in this line item
foreach ($lineItem as $segment) { … } // …or iterate them
}
foreach ($message->contextSegments() as $context) {
if ($context->tag() === 'NAD') {
foreach ($context as $child) { // …or ->children()
// $child->tag(), $child->rawValues(), …
}
$context->childByTag('CTA'); // ?SegmentInterface — the first one
$context->childrenByTag('COM'); // list<SegmentInterface> — all of them
$context->hasChildren(); // bool
count($context); // number of children
$context->toArray(); // the segment with its children nested
}
}
$buyer = $message->segmentByTagAndSubId('NAD', 'BY'); // NADNameAddress
$buyer?->name(); // typed accessors work
$message->childrenOf($buyer); // list<SegmentInterface> — the CTA/COM under this NAD
$message->contextFor($buyer); // ?ContextSegment — the same, as a context object
foreach ($result->functionalGroups() as $group) {
$group->messageType(); // e.g. 'ORDERS' (from the UNG)
$group->header()->groupReference();
$group->trailer()?->controlCount();
foreach ($group as $message) { // …or ->messages()
// …
}
count($group); // messages in the group
}
use EdifactParser\Analysis\MessageAnalyzer;
$analyzer = new MessageAnalyzer($message);
$analyzer->getType(); // 'ORDERS'
$analyzer->segmentCount();
$analyzer->lineItemCount();
$analyzer->segmentCountByTag('QTY');
$analyzer->getPartyQualifiers(); // ['BY', 'SU', 'CN'] (unique)
$analyzer->getCurrencies(); // ['EUR']
$analyzer->calculateTotalAmount('125'); // sum MOA with qualifier 125
$analyzer->calculateTotalQuantity('21'); // sum ordered quantities
$analyzer->hasSummarySection(); // UNS present?
$analyzer->getSummary(); // array of the above
use EdifactParser\Validation\MessageRuleSet;
use EdifactParser\Validation\MessageValidator;
$rules = MessageRuleSet::forType('ORDERS')
-> ->inSequence('UNH', 'BGM', 'UNT'); // relative order of these tags
$validator = new MessageValidator();
foreach ($validator->validate($message, $rules) as $violation) {
echo "{$violation->segmentTag()}: {$violation->message()}\n";
}
$validator->isValid($message, $rules); // bool
use EdifactParser\Validation\MessageRuleSets;
$validator->validate($message, MessageRuleSets::orders()); // orders(), invoic(), desadv(), iftmin()
namespace YourApp\Segments;
use EdifactParser\Segments\AbstractSegment;
/** @psalm-immutable */
final class EQDEquipmentDetails extends AbstractSegment
{
public function tag(): string
{
return 'EQD';
}
// EQD+CN+ABCU1234567+22G1
public function equipmentQualifier(): string
{
return $this->element(1); // 'CN'
}
public function equipmentId(): string
{
return $this->firstComponent(2); // 'ABCU1234567'
}
}
use EdifactParser\EdifactParser;
use EdifactParser\Segments\SegmentFactory;
use YourApp\Segments\EQDEquipmentDetails;
$factory = SegmentFactory::withAdditionalSegments([
'EQD' => EQDEquipmentDetails::class, // added on top of the 32 built-ins
]);
$parser = new EdifactParser($factory);
// Envelope structure + just the segments you extract:
$factory = SegmentFactory::withSegments(
SegmentFactory::ENVELOPE_SEGMENTS + [
'NAD' => NADNameAddress::class,
'LIN' => LINLineItem::class,
],
);
use EdifactParser\EdifactParser;
use EdifactParser\GroupingRules;
use EdifactParser\Segments\SegmentFactory;
use EdifactParser\StreamingParser;
$rules = GroupingRules::default()
->withContextTags(['NAD', 'LIN'])
->withChildTags(['CTA', 'COM', 'DTM'])
->withBreakLineItemTags(['UNS', 'CNT', 'UNT']);
$parser = new EdifactParser(SegmentFactory::withDefaultSegments(), $rules);
// …or, when the default segments are all you need:
$parser = EdifactParser::createWithDefaultSegments($rules);
$stream = StreamingParser::createWithDefaultSegments($rules);