Search by

kraenzle-ritter / exif-extract

ottosmops

Unified PHP interface for extracting technical metadata (EXIF, IPTC, XMP, …) from media files using ExifTool.

Package info

github.com/kraenzle-ritter/exif-extract

pkg:composer/kraenzle-ritter/exif-extract

Statistics

Installs: 3

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v0.1.0 2026-10-17 13:04 UTC

This package is auto-updated.

Last update: 2026-10-17 13:10:03 UTC


README

CI Latest Version Downloads PHP Version License

exif-extract is a PHP library for extracting technical metadata (EXIF, IPTC, XMP, …) from media files. It wraps the ExifTool CLI behind a small engine abstraction so applications get strongly-typed results without re-implementing the proc_open / chunked-batch / encoding-recovery plumbing on every call site.

This is the sibling package of kraenzle-ritter/puidentify (format identification via PRONOM PUIDs) — both packages share the same engine-manager pattern.

Installation

composer require kraenzle-ritter/exif-extract

Requirements

  • PHP 8.1 or higher
  • ExifTool installed and available in PATH (the exiftool command).

Quick Start

use ExifExtract\ExifIdentifier;
use ExifExtract\Engine\ExifToolEngine;

$identifier = new ExifIdentifier([new ExifToolEngine()]);

$result = $identifier->extract('/path/to/photo.jpg');

if ($result !== null) {
    echo $result->engineVersion;   // "13.50"
    echo $result->metadata['EXIF:Make'] ?? '(no make)';
    echo $result->metadataCount();
}

Batch Mode

For ingesting many files, use extractBatch() — the engine batches the underlying exiftool invocations (default chunk size: 500 files) and falls back to per-file mode for any chunk that errors out.

$paths = [
    '/path/to/a.jpg',
    '/path/to/b.tif',
    '/path/to/c.jp2',
];

$results = $identifier->extractBatch($paths);

foreach ($results as $path => $result) {
    if ($result === null) {
        // File was missing, oversized, or no metadata extracted.
        continue;
    }
    // … process $result->metadata
}

Custom Binary Path

$engine = new ExifToolEngine('/opt/homebrew/bin/exiftool');

Tuning the Engine

$engine = new ExifToolEngine('exiftool', [
    'per_file_timeout' => 60,         // seconds, default 30
    'batch_timeout_floor' => 30,      // seconds
    'batch_timeout_ceiling' => 300,   // seconds
    'chunk_size' => 250,              // files per exiftool invocation
    'max_file_size' => 100 * 1024 * 1024, // 100 MB skip
]);

Engine Interface

ExifExtract\Engine\EngineInterface allows alternative implementations (e.g. a pure-PHP getimagesize-based fallback or an ImageMagick wrapper) to be plugged into ExifIdentifier without changes to consumers.

interface EngineInterface
{
    public function extract(string $filePath): ?ExifResult;

    /** @param string[] $filePaths */
    public function extractBatch(array $filePaths): array;

    public function isAvailable(): bool;
    public function getName(): string;
    public function getVersion(): ?string;
}

Result Object

ExifExtract\Result\ExifResult is a small immutable value object:

Property Type Description
sourceFile string Absolute path of the source file
metadata array<string, mixed> Group-prefixed flat array as returned by exiftool -j -G
engine string Engine name (e.g. "ExifTool")
engineVersion ?string Engine version (e.g. "13.50")

metadata keys carry the ExifTool group prefix: EXIF:Make, File:FileSize, XMP-dc:Title. The SourceFile key from ExifTool is preserved inside metadata so consumers can correlate.

Exceptions

All exceptions extend ExifExtract\Exception\ExifExtractException.

Exception Thrown when
FileNotFoundException The input file does not exist or is unreadable
FileTooLargeException The file exceeds the configured max_file_size
TimeoutException The ExifTool invocation exceeded its timeout
EngineException The binary is missing, returned no output, or returned unparseable JSON

Testing

composer install
vendor/bin/phpunit

Engine-level tests are skipped automatically if exiftool is not in the PATH. The ExifIdentifier tests use stub engines and run without any external binary.

License

MIT — see LICENSE.