jamesmorrison / metar
A PHP 8.4 METAR weather report parser. Parses raw METAR strings into structured, readonly value objects with full remark support and human-readable labels.
Requires
- php: ^8.4
Requires (Dev)
- laravel/pint: ^1.29.1
- pestphp/pest: ^4.7
- pestphp/pest-plugin-arch: ^4.0.2
- phpstan/extension-installer: ^1.4.3
- phpstan/phpstan-deprecation-rules: ^2.0.4
- phpstan/phpstan-phpunit: ^2.0.16
- rector/rector: ^2.4
- roave/security-advisories: dev-latest
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-10-11 20:14:16 UTC
README
A PHP 8.4 METAR weather report parser. Parses raw METAR strings into structured, readonly value objects with full remark support and human-readable labels.
Installation
composer require jamesmorrison/metar
Requires PHP 8.4 or higher.
Usage
use JamesMorrison\Metar\Parser; $metar = new Parser('METAR EGLL 141250Z 24015G25KT 9999 FEW040CB 12/08 Q1015 NOSIG');
Accessing Components
Every component is a readonly value object with typed properties and a label() method:
$metar->station->icao; // 'EGLL' $metar->observationTime->day; // 14 $metar->observationTime->hour; // 12 $metar->observationTime->minute; // 50 $metar->wind->direction; // 240 $metar->wind->speed; // 15 $metar->wind->gusts; // 25 $metar->wind->unit; // WindUnit::Knots $metar->wind->speedKnots; // 15.0 $metar->wind->speedMps; // 7.7 $metar->visibility->distance; // 9999.0 $metar->visibility->unit; // VisibilityUnit::Metres $metar->clouds[0]->amount; // CloudAmount::Few $metar->clouds[0]->height; // 4000 $metar->clouds[0]->type; // CloudType::Cumulonimbus $metar->temperature->temperature; // 12 $metar->temperature->dewpoint; // 8 $metar->pressure->hectopascals; // 1015.0 $metar->pressure->inchesOfMercury; // 29.97
Human-Readable Labels
All components implement Labelable and Stringable:
$metar->wind->label(); // 'Wind from 240 degrees at 15 knots gusting 25 knots' $metar->pressure->label(); // '1015 hPa / 29.97 inHg' echo $metar->temperature; // 'Temperature 12°C (54°F), dewpoint 8°C (46°F)' // Full METAR summary echo $metar->label();
JSON Serialization
The parser implements JsonSerializable:
json_encode($metar, JSON_PRETTY_PRINT);
CAVOK
When CAVOK is reported, visibility/weather/clouds are not parsed:
$metar = new Parser('METAR EGLL 141250Z 24015KT CAVOK 12/08 Q1015'); $metar->cavok; // true
Parsed Components
| Property | Type | Description |
|---|---|---|
station |
?Station |
ICAO station identifier |
observationTime |
?ObservationTime |
Day, hour, and minute (UTC) |
modifiers |
Modifier[] |
AUTO, COR, etc. |
wind |
?Wind |
Direction, speed, gusts, unit (with dual-unit conversions) |
windVariation |
?WindVariation |
Variable wind direction range |
visibility |
?Visibility |
Prevailing visibility (with dual-unit conversions) |
directionalVisibility |
DirectionalVisibility[] |
Sector-specific visibility |
runwayVisualRange |
RunwayVisualRange[] |
RVR per runway |
weather |
Weather[] |
Present weather phenomena |
clouds |
Cloud[] |
Cloud layers |
temperature |
?Temperature |
Temperature and dewpoint (Celsius + Fahrenheit) |
pressure |
?Pressure |
Altimeter setting (hPa + inHg) |
windShear |
?WindShear |
Wind shear warnings |
recentWeather |
RecentWeather[] |
Recent weather phenomena |
trends |
Trend[] |
NOSIG, TEMPO, BECMG trends |
remarks |
?Remarks |
Decoded remark groups |
cavok |
bool |
Ceiling and visibility OK |
Remarks
The parser decodes 25+ remark types including:
- Station type (AO1/AO2)
- Sea-level pressure
- Peak wind and wind shift
- Hourly temperature / temperature extremes
- Pressure tendency and rapid pressure change
- Precipitation (hourly, 3/6-hour, 24-hour)
- Lightning (frequency, type, direction)
- Weather events (beginning/ending times)
- Variable ceiling and visibility
- Significant clouds (CB, TCU, ACC, etc.)
- Virga, obscurations, snow depth/increase
- Sensor status and maintenance indicators
$metar = new Parser('METAR KJFK 141250Z 24015KT 10SM FEW040 12/08 A2997 RMK AO2 SLP153 T01170083'); foreach ($metar->remarks->groups as $remark) { echo $remark->label() . "\n"; }
Testing
composer pest # Run tests composer analyse # PHPStan (max level) composer pint # Code style composer test # All of the above
License
MIT