You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: CHANGELOG.md
+33Lines changed: 33 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,6 +2,39 @@
2
2
3
3
All notable changes to `mrz-parser` will be documented in this file.
4
4
5
+
## v2.0.0 - 2026-07-01
6
+
7
+
### Breaking changes
8
+
9
+
- Minimum PHP version is now **8.2** (was 8.0).
10
+
-`parse()` now returns additional keys (`issuer_code`, `nationality_code`, `sex`, `optional_data`, `valid`, `validation`, `raw`). Existing keys are unchanged.
11
+
-`Enums\DocumentType` is now a real backed enum instead of an abstract class with constants.
12
+
13
+
### Added
14
+
15
+
-**ICAO 9303 check-digit validation.** Each result exposes an overall `valid` flag plus a per-field `validation` map (document number, date of birth, date of expiry, personal number, and composite).
16
+
- Richer output: raw ISO alpha-3 codes (`issuer_code`, `nationality_code`), raw `sex` character, `optional_data`, and the normalized `raw` MRZ string.
17
+
-**Typed `MrzResult` object** via `MrzParser::read()` — typed properties, `dateOfBirthAsDate()`/`dateOfExpiryAsDate()`, `isExpired()`, `fullName()`, and `toArray()`.
18
+
-**Non-throwing entry points**`MrzParser::tryParse()` and `MrzParser::tryRead()` returning `null` on invalid input.
19
+
-**Strict check-digit mode** (`parse($text, strict: true)`) throwing `InvalidChecksumException` when a check digit fails.
20
+
-**Name transliteration** (`Support\Transliterator`): `fromLatin()` and `matches()` for converting/comparing accented names against the MRZ.
21
+
-**French national ID** (2×36 legacy format) support.
22
+
-**Laravel integration**: auto-discovered service provider and a `ValidMrz` validation rule.
23
+
- A full Pest test suite (parsers, validator, check digits, mappers, DTO, transliteration, Laravel rule) with ~99% coverage.
24
+
25
+
### Fixed
26
+
27
+
- CRLF / whitespace input is now normalized, so Windows- and OCR-sourced MRZ strings parse correctly instead of failing validation.
28
+
- Strict date validation rejects impossible calendar dates (e.g. Feb 30) instead of silently rolling them over.
29
+
- A date of birth that would resolve to the future is shifted back a century.
30
+
- Removed a PHP 8.4 implicit-nullable deprecation and guarded against `substr(null, ...)` on missing rows.
31
+
- Consistent trailing-filler trimming for given names across all document types.
32
+
33
+
### Changed
34
+
35
+
- Modernized the codebase: `declare(strict_types=1)`, typed properties, `match`-based adapter selection, and a cached country lookup table.
36
+
- CI now tests PHP 8.2, 8.3, 8.4 and 8.5; upgraded to Pest 3.
Copy file name to clipboardExpand all lines: README.md
+99-1Lines changed: 99 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,10 +2,20 @@
2
2
# MRZ (Machine Readable Zones) Parser for PHP
3
3
4
4
[](https://packagist.org/packages/rakibdevs/mrz-parser)
A PHP package for MRZ (Machine Readable Zones) code parser for Passport, Visa & Travel Document (TD1 & TD2).
8
12
13
+
It reads the machine-readable zone, extracts the document fields, and — new in v2 — verifies the ICAO 9303 check digits so you can tell whether the data is internally consistent.
Every result carries a `valid` flag (overall) and a `validation` map with the outcome of each ICAO 9303 check digit (`card_no`, `date_of_birth`, `date_of_expiry`, `personal_number` for passports, and the `composite`). Visas carry no composite check digit, so their `validation` map omits it. Use these to reject OCR mistakes or tampered documents.
70
+
71
+
### Input handling
72
+
73
+
Input is normalized before parsing: `\r\n` / `\r` line endings are converted to `\n`, surrounding whitespace is trimmed, and blank lines are dropped — so MRZ strings copied from Windows or OCR output parse the same as clean input. Dates are validated strictly (impossible dates such as Feb 30 return `null`), and a date of birth that would resolve to the future is shifted back a century.
74
+
75
+
## Advanced usage
76
+
77
+
### Typed result object
78
+
79
+
`read()` returns an `MrzResult` value object with typed properties and helpers, while `toArray()` gives you the same array as `parse()`:
80
+
81
+
```php
82
+
$mrz = MrzParser::read($text);
83
+
84
+
$mrz->cardNo; // 'L898902C3'
85
+
$mrz->fullName(); // 'ANNAMARIAERIKSSON'
86
+
$mrz->dateOfBirthAsDate(); // DateTimeImmutable
87
+
$mrz->isExpired(); // bool (or null when the format has no expiry)
88
+
$mrz->valid; // bool
89
+
$mrz->toArray(); // the canonical parse() array
90
+
```
91
+
92
+
### Non-throwing parsing
93
+
94
+
`parse()`/`read()` throw on unrecognised input. Use the `try*` variants to get `null` instead:
95
+
96
+
```php
97
+
MrzParser::tryParse($text); // ?array
98
+
MrzParser::tryRead($text); // ?MrzResult
99
+
```
100
+
101
+
### Strict check-digit mode
102
+
103
+
Pass `strict: true` to reject documents whose check digits don'tverify(throws`InvalidChecksumException`;the`try*`variantsreturn`null`):
0 commit comments