PHP code example of avvertix / dmarc-report-parser

1. Go to this page and download the library: Download avvertix/dmarc-report-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/ */

    

avvertix / dmarc-report-parser example snippets


$dmarc = new Avvertix\DmarcReportParser\DmarcReportParser();

/**
 * @var Avvertix\DmarcReportParser\Data\DmarcReport
 */
$report = $dmarc->fromFile('path/to/report.xml');

// Who generated the report, and for which reporting window
$report->org_name;                             // 'Enterprise Outlook'
$report->email;                                // '[email protected]'
$report->report_id;                            // '[email protected]'
$report->date_range->begin;                    // DateTimeImmutable
$report->date_range->end->format('Y-m-d');     // '2024-11-26'

// The policy the receiver found for the domain
$report->publishedPolicy->domain;              // 'a-domain.localhost'
$report->publishedPolicy->p->value;            // 'reject'

// One record per sending IP
foreach ($report->records as $record) {
    $record->row->source_ip;                                  // '255.255.255.253'
    $record->row->count;                                      // 7
    $record->row->policy_evaluated->disposition->value;       // 'none', 'quarantine', 'reject' or 'pass'
    $record->identifiers->header_from;                        // 'a-domain.localhost'
}

use Avvertix\DmarcReportParser\DmarcReportParser;
use Avvertix\DmarcReportParser\ParserConfiguration;

$dmarc = new DmarcReportParser(new ParserConfiguration(
    maxDecompressedBytes: 2 * 1024 * 1024, // 2 MB
));

$dmarc = new Avvertix\DmarcReportParser\DmarcReportParser();

$xml = <<<'DMARC'
<?xml version="1.0"

foreach ($report->records as $record) {
    // Zero or more DKIM signatures were evaluated for this group of messages
    foreach ($record->auth_results->dkim as $dkim) {
        $dkim->domain;              // 'a-domain.localhost'
        $dkim->selector;            // 'selector1', or null on RFC 7489-era reports
        $dkim->result->value;       // 'pass'
        $dkim->human_result;        // 'signature verified', or null
    }

    // Zero or one SPF result. The array is empty when the report carries none
    foreach ($record->auth_results->spf as $spf) {
        $spf->domain;               // 'a-domain.localhost'
        $spf->scope;                // 'mfrom', or null
        $spf->result->value;        // 'pass'
    }

    // Present when the receiver did not apply the published policy
    foreach ($record->row->policy_evaluated->reasons as $reason) {
        $reason->type->value;       // 'policy_test_mode'
        $reason->comment;           // 'policy in testing mode', or null
    }
}

use Avvertix\DmarcReportParser\Data\DispositionType;
use Avvertix\DmarcReportParser\Data\DmarcResultType;

// How many messages does this report cover?
$messages = array_sum(array_map(fn ($record) => $record->row->count, $report->records));

// Which messages failed DMARC on both mechanisms? These are the ones worth investigating
$failing = array_filter(
    $report->records,
    fn ($record) => $record->row->policy_evaluated->dkim === DmarcResultType::FAIL
        && $record->row->policy_evaluated->spf === DmarcResultType::FAIL
);

// Which messages were actually quarantined or rejected?
$enforced = array_filter(
    $report->records,
    fn ($record) => in_array(
        $record->row->policy_evaluated->disposition,
        [DispositionType::QUARANTINE, DispositionType::REJECT],
        true
    )
);

// Which DKIM selectors are in use? Reports are the only place to discover them,
// as DNS cannot be queried for every selector on a domain
$selectors = [];

foreach ($report->records as $record) {
    foreach ($record->auth_results->dkim as $dkim) {
        if ($dkim->selector !== null) {
            $selectors[$dkim->selector] = true;
        }
    }
}

$selectors = array_keys($selectors);

// Which sending IPs are responsible for the most messages?
$byVolume = [];

foreach ($report->records as $record) {
    $byVolume[$record->row->source_ip] ??= 0;
    $byVolume[$record->row->source_ip] += $record->row->count;
}

arsort($byVolume);

use Avvertix\DmarcReportParser\ReportFilename;

$parsedFilename = ReportFilename::parse('mail.receiver.example!example.com!1013662812!1013749130.xml.gz');

$parsedFilename->receiver;      // 'mail.receiver.example'
$parsedFilename->policy_domain; // 'example.com'
$parsedFilename->date_range;    // DateRange
$parsedFilename->unique_id;     // null
$parsedFilename->compressed;    // true