Getting Started
Upon the day of ashes, draw a narrow door of salt upon the chapel floor. Let the penitent cross it barefoot, naming the restitution already made, and suffer none to sweep behind them. At evening, if the door remaineth whole, their sorrow lacked weight; if their feet have broken it, admit them to the choir, and let the first hymn be for those they harmed.
— Ordinances of the Synthetic Dawn 34:72
Yumemi requires PHP 8.2 or later and the GMP extension, which provides the arbitrary-precision integers used for exact rational arithmetic and conversion.
Installation
Most applications call Yumemi at runtime and also use its PHPStan extension. Install it as a normal application dependency:
composer require jbboehr/yumemi:^0.1
Yumemi does not install PHPStan automatically in consuming projects. Install PHPStan and the extension installer as development dependencies to enable automatic registration:
composer require --dev phpstan/phpstan:^2.2.5 phpstan/extension-installer
Projects that do not use phpstan/extension-installer should install
PHPStan by itself and include Yumemi explicitly from phpstan.neon:
includes:
- vendor/jbboehr/yumemi/extension.neon
Keep jbboehr/yumemi as a normal dependency whenever application code calls functions such as unit() or unit_to(),
or uses runtime classes such as Units and Quantity. A project using Yumemi only during static analysis, with no
runtime calls or classes, may install it as a development dependency instead.
Verify Static Analysis
Configure at least one source path for PHPStan. For an application whose PHP code lives under src/, a minimal
phpstan.neon is:
parameters:
level: 8
paths:
- src
When automatic extension registration is unavailable, add the includes entry shown in Installation to
the same file.
Use unit() to brand an ordinary native value at a system boundary. PHPStan then carries the unit through arithmetic
and rejects a deliberately incorrect result. Place this example under a configured path, such as src/YumemiCheck.php:
<?php
require 'vendor/autoload.php';
use function jbboehr\Yumemi\unit;
/** @param unit_float<'meter / second'> $speed */
function saveJourneySpeed(float $speed): void {}
$distance = unit(100.0, 'meter');
$duration = unit(10.0, 'second');
$speed = $distance / $duration;
saveJourneySpeed($speed);
assert($speed === 10.0);
// @akashi-phpstan-error argument.type: unit_float<'meter / second'>, 1000.0&unit_float<'meter * second'> given
saveJourneySpeed($distance * $duration);
Run the PHPStan command used by your project, or the default executable directly:
vendor/bin/phpstan analyse
PHPStan should accept $speed and report the expected unit mismatch for the final call. The @akashi-phpstan-error
line records the diagnostic identifier and a distinctive fragment of the expected message; it is an ordinary comment,
not a required annotation. Remove the incorrect call once the extension is working.
If PHPStan instead reports unknown unit_int or unit_float PHPDoc types, the extension is not registered. Install
phpstan/extension-installer or add Yumemi’s extension.neon include explicitly.
If the deliberately incorrect call produces no diagnostic, confirm that the example file is under one of the configured
paths, that the invalid call remains in the file, and that the command is loading the phpstan.neon where Yumemi is
registered.
The runtime values remain ordinary floats. The additional unit information exists only in PHPStan’s type system.
Most applications should use Yumemi’s PHPDoc types directly. Libraries that cannot require Yumemi from every consumer
can instead use the deliberately opt-in
@yumemi-* annotation integration.
Runtime Conversion
The runtime unit engine can be used independently of PHPStan brands and extension registration. Use Units and
Quantity when the application must perform a conversion or retain exact rational values:
<?php
require 'vendor/autoload.php';
use jbboehr\Yumemi\Units;
$length = Units::default()->quantity(1, 'mile')->to('kilometer');
assert($length->exactDecimalValueIn('kilometer') === '1.609344');
assert($length->unitToString() === 'kilometer');
For more runtime-only examples, see Preserve Exact Conversion and Convert Temperatures. Continue with Core Concepts, then use the PHPStan, unit syntax, and runtime API references as needed.