Search by

cloud-castle / unit-convertor

alex-4-17

Конвертер единиц измерения для PHP 8.1+: 99 категорий и 577 единиц (СИ, имперские, США, морские, астрономические, исторические русские), размерностный анализ величин, температурные шкалы и дельты, составные величины (5 ft 3 in), SI/IEC-префиксы, произвольная точность на cloud-castle/match, внешние с

v1.1.0 2026-10-01 09:41 UTC

This package is auto-updated.

Last update: 2026-10-05 05:43:13 UTC


README

🇷🇺 Русский · 🇬🇧 English · 🇩🇪 Deutsch · 🇫🇷 Français · 🇪🇸 Español · 🇮🇹 Italiano

CloudCastle UnitConvertor

CloudCastle UnitConvertor

Packagist Version PHP Version License Total Downloads Monthly Downloads Daily Downloads Stars Dependents Security advisories

Repository Issues CI Release

PHPStan Psalm PHPCS PHPMD Coverage Infection MSI OpenSSF Scorecard

Конвертер единиц измерения для PHP 8.1+: 99 категорий и 577 единиц (СИ, имперские, США, морские, астрономические, исторические русские), размерностный анализ величин (10 м / 2 с = 5 м/с), физически корректные температуры (8 шкал + дельты Δ°C), составные величины («5 ft 3 in»), динамические SI/IEC-префиксы (кветто…кветта, KiB…YiB), произвольная точность на cloud-castle/match, внешние справочники единиц, локализация на 6 языков с плюрализацией, парсинг и форматирование. Единственная runtime-зависимость — cloud-castle/match.

Установка

composer require cloud-castle/unit-convertor

Требуется PHP 8.1+ (проверено вплоть до 8.5).

Быстрый старт

<?php

use CloudCastle\UnitConvertor\Converter;
use CloudCastle\UnitConvertor\Quantity;

$converter = new Converter();

// Простая конверсия — 0.2 мкс на операцию после прогрева пары
$converter->convert(5, 'km', 'mi');            // 3.10685596…
$converter->convert(100, 'celsius', 'fahrenheit'); // 212.0
$converter->convert(8, 'L/100km', 'mpg_us');   // 29.4018… (нелинейная)
$converter->convert(1, 'GiB', 'MB');           // 1073.741824 (IEC ↔ СИ)
$converter->convert(1, 'кВтч', 'Дж');          // русские алиасы работают

// Величины-объекты: иммутабельные, с арифметикой и размерностным анализом
$speed = Quantity::of(100, 'km')->div(Quantity::of(2, 'h'));
$speed->code();                                 // 'm/s'
$speed->to('km/h')->value();                    // 50.0

// Физически корректные температуры
Quantity::of(30, 'celsius')->sub(Quantity::of(20, 'celsius')); // 10 Δ°C
Quantity::of(20, 'celsius')->add(Quantity::of(18, 'delta_fahrenheit')); // 30 °C
// Quantity::of(30, 'celsius')->add(Quantity::of(20, 'celsius')); — исключение!

// Парсинг, разложение, форматирование
Quantity::parse('5 ft 3 in')->to('cm')->value();          // 160.02
Quantity::of(5025, 's')->toCompound(['h', 'min', 's']);   // 1 ч 23 мин 45 с
Quantity::of(1500, 'm')->humanize();                      // «1,5 км»
Quantity::of(5, 'km')->format(1, 'ru', long: true);       // «5 километров»

// Произвольная точность (BCMath через cloud-castle/match)
$converter->convertPrecise('1', 'ly', 'km'); // '9460730472580.8' — точно

Возможности

  • 99 категорий, 577 единиц из коробки — от длины и массы до дозиметрии (мкЗв/ч, пКи/л), молярных концентраций (°dH жёсткости воды), темпа бега (мин/км), газовых отметок духовки и русских исторических мер (пуд, аршин, верста). Полный список — в wiki.
  • Размерностный анализ: умножение и деление величин выводит размерность результата; произведение силы на длину само становится джоулями, а неизвестные размерности синтезируются на лету.
  • Физическая корректность температур: 8 шкал (включая Реомюра, Делиля, Рёмера), дельта-единицы, запрет бессмысленных операций.
  • Динамические префиксы: любые СИ-приставки от кветто (10⁻³⁰) до кветта (10³⁰) и IEC-приставки KiB…YiB — без раздувания данных, с точными строковыми множителями.
  • Внешние справочники: свой каталог данных, attachSource() поверх встроенного, программные категории registerCategory() — с генератором индексов IndexBuilder и защитой от перехвата чужих кодов.
  • Локализация: символы и имена единиц на 6 языках с корректной плюрализацией («5,5 километра», «2 kilometres», «1,5 kilomètre»).
  • Произвольная точность: convertPrecise() на BigDecimal из cloud-castle/match — 100 знаков после запятой.
  • Скорость: pair-кэш сводит линейную конверсию к одному умножению и сложению — ~0.2 мкс на операцию.

Сравнение с аналогами

Все таблицы ниже сгенерированы автоматически стендом benchmarks/ (compare.php → analysis.php → generate.php): каждый пакет установлен изолированно в var/analogs/<пакет> — включая сам cloud-castle/unit-convertor в установке без dev-зависимостей — и измерен в отдельном процессе без Xdebug (замеры — PHP 8.3.35, анализ — PHP 8.3.35). Жирным выделено лучшее значение строки.

Сводка по этапам

Сколько строк каждого раздела выиграл пакет (ничьи не засчитываются).

Этапunit-convertorjordanbrauerphp-units-of-measurecrisu83cartalystmeasurements🏆 Победитель
Функциональность300000unit-convertor
Правильность431011unit-convertor
phplint110000unit-convertor, jordanbrauer
Psalm400000unit-convertor
PHPStan400000unit-convertor
PHPMD200000unit-convertor
PHPCS310000unit-convertor
Rector300000unit-convertor
Deptrac100000unit-convertor
Мутационное тестирование200000unit-convertor
Безопасность1615442unit-convertor
Потребление памяти201110012measurements
Утечки памяти120109210unit-convertor
Производительность1300100unit-convertor
Качество511010unit-convertor
Всего7572824825unit-convertor

1. Функциональность

Возможности сняты исполняемыми пробами (benchmarks/capabilities.php): каждая проба вызывает API пакета и проверяет правильность ответа — «есть метод» не засчитывается, неверный результат тоже. Таблица перечисляет объединение возможностей всех пакетов; интеграции с фреймворками (Laravel у cartalyst) не сравниваются.

Метрикаunit-convertorjordanbrauerphp-units-of-measurecrisu83cartalystmeasurements🏆 Победитель
Возможностей всего692327181028unit-convertor
Уникальных (нет ни у одного другого пакета)1900000unit-convertor
Покрыто возможностей остальных пакетов100,0 %33,3 %39,1 %26,1 %14,5 %40,6 %unit-convertor
Полная матрица: все возможности всех пакетов | Возможность | **unit-convertor** | jordanbrauer | php-units-of-measure | crisu83 | cartalyst | measurements | 🏆 Победитель | |---|:---:|:---:|:---:|:---:|:---:|:---:|---| | Сложение и вычитание величин (`add_sub`) | **✅** | ❌ | **✅** | **✅** | ❌ | **✅** | unit-convertor, php-units-of-measure, crisu83, measurements | | Защита от бессмысленной арифметики абсолютных шкал (`affine_guard`) | **✅** | ❌ | ❌ | ❌ | ❌ | ❌ | unit-convertor | | Агрегаты: сумма, среднее, минимум, максимум (`aggregates`) | **✅** | ❌ | ❌ | ❌ | ❌ | ❌ | unit-convertor | | Произвольная точность (BCMath) (`arbitrary_precision`) | **✅** | ❌ | ❌ | ❌ | ❌ | ❌ | unit-convertor | | Автовыбор удобной единицы (`auto_unit`) | **✅** | ❌ | ❌ | ❌ | ❌ | ❌ | unit-convertor | | Пакетная и ленивая конверсия (`batch_conversion`) | **✅** | ❌ | ❌ | ❌ | ❌ | ❌ | unit-convertor | | Проверка возможности конверсии (`can_convert`) | **✅** | ❌ | ❌ | ❌ | ❌ | **✅** | unit-convertor, measurements | | Категория: ускорение (`cat_acceleration`) | **✅** | ❌ | **✅** | **✅** | ❌ | ❌ | unit-convertor, php-units-of-measure, crisu83 | | Категория: количество вещества (`cat_amount`) | **✅** | ❌ | **✅** | ❌ | ❌ | ❌ | unit-convertor, php-units-of-measure | | Категория: угол (`cat_angle`) | **✅** | **✅** | **✅** | **✅** | ❌ | **✅** | unit-convertor, jordanbrauer, php-units-of-measure, crisu83, measurements | | Категория: полная мощность (В·А) (`cat_apparent_power`) | **✅** | ❌ | ❌ | **✅** | ❌ | ❌ | unit-convertor, crisu83 | | Категория: площадь (`cat_area`) | **✅** | **✅** | **✅** | ❌ | **✅** | **✅** | unit-convertor, jordanbrauer, php-units-of-measure, cartalyst, measurements | | Категория: электрический заряд (`cat_charge`) | **✅** | ❌ | ❌ | ❌ | ❌ | **✅** | unit-convertor, measurements | | Категория: валюты по курсам (`cat_currency`) | **✅** | ❌ | ❌ | ❌ | **✅** | ❌ | unit-convertor, cartalyst | | Категория: объём данных (`cat_data`) | **✅** | **✅** | ❌ | ❌ | ❌ | ❌ | unit-convertor, jordanbrauer | | Категория: сила тока (`cat_electric_current`) | **✅** | ❌ | **✅** | **✅** | ❌ | **✅** | unit-convertor, php-units-of-measure, crisu83, measurements | | Категория: энергия (`cat_energy`) | **✅** | **✅** | **✅** | **✅** | ❌ | **✅** | unit-convertor, jordanbrauer, php-units-of-measure, crisu83, measurements | | Категория: частота (`cat_frequency`) | **✅** | **✅** | ❌ | **✅** | ❌ | **✅** | unit-convertor, jordanbrauer, crisu83, measurements | | Категория: расход топлива (обратная шкала) (`cat_fuel_economy`) | **✅** | **✅** | ❌ | ❌ | ❌ | ❌ | unit-convertor, jordanbrauer | | Категория: размеры головных уборов (`cat_hat_size`) | **✅** | ❌ | ❌ | ❌ | ❌ | ❌ | unit-convertor | | Категория: освещённость (`cat_illuminance`) | **✅** | ❌ | ❌ | ❌ | ❌ | **✅** | unit-convertor, measurements | | Категория: длина (`cat_length`) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ничья | | Категория: сила света (`cat_luminous_intensity`) | **✅** | ❌ | **✅** | **✅** | ❌ | ❌ | unit-convertor, php-units-of-measure, crisu83 | | Категория: масса (`cat_mass`) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ничья | | Категория: массовая концентрация (`cat_mass_concentration`) | **✅** | ❌ | ❌ | ❌ | ❌ | **✅** | unit-convertor, measurements | | Категория: мощность (`cat_power`) | **✅** | ❌ | **✅** | **✅** | ❌ | **✅** | unit-convertor, php-units-of-measure, crisu83, measurements | | Категория: давление (`cat_pressure`) | **✅** | **✅** | **✅** | **✅** | ❌ | **✅** | unit-convertor, jordanbrauer, php-units-of-measure, crisu83, measurements | | Категория: радиоактивность (`cat_radioactivity`) | **✅** | ❌ | ❌ | ❌ | ❌ | **✅** | unit-convertor, measurements | | Категория: сопротивление (`cat_resistance`) | **✅** | ❌ | ❌ | ❌ | ❌ | **✅** | unit-convertor, measurements | | Категория: размеры обуви (`cat_shoe_size`) | **✅** | ❌ | ❌ | ❌ | ❌ | ❌ | unit-convertor | | Категория: телесный угол (`cat_solid_angle`) | **✅** | ❌ | **✅** | ❌ | ❌ | ❌ | unit-convertor, php-units-of-measure | | Категория: скорость (`cat_speed`) | **✅** | **✅** | **✅** | **✅** | ❌ | **✅** | unit-convertor, jordanbrauer, php-units-of-measure, crisu83, measurements | | Категория: температура (аффинные шкалы) (`cat_temperature`) | **✅** | **✅** | **✅** | ❌ | **✅** | **✅** | unit-convertor, jordanbrauer, php-units-of-measure, cartalyst, measurements | | Категория: время (`cat_time`) | **✅** | **✅** | **✅** | **✅** | ❌ | **✅** | unit-convertor, jordanbrauer, php-units-of-measure, crisu83, measurements | | Категория: напряжение (`cat_voltage`) | **✅** | ❌ | ❌ | **✅** | ❌ | **✅** | unit-convertor, crisu83, measurements | | Категория: объём (`cat_volume`) | **✅** | **✅** | **✅** | **✅** | ❌ | **✅** | unit-convertor, jordanbrauer, php-units-of-measure, crisu83, measurements | | Сравнение величин (`compare`) | **✅** | ❌ | ❌ | ❌ | ❌ | **✅** | unit-convertor, measurements | | Журнал конверсий (`conversion_log`) | **✅** | **✅** | ❌ | ❌ | ❌ | ❌ | unit-convertor, jordanbrauer | | Конверсия во все единицы категории (`convert_to_all`) | **✅** | **✅** | ❌ | ❌ | ❌ | ❌ | unit-convertor, jordanbrauer | | Регистрация своей категории (`custom_category`) | **✅** | **✅** | ❌ | ❌ | **✅** | ❌ | unit-convertor, jordanbrauer, cartalyst | | Регистрация своей единицы (`custom_unit`) | **✅** | **✅** | **✅** | ❌ | **✅** | **✅** | unit-convertor, jordanbrauer, php-units-of-measure, cartalyst, measurements | | Температурные дельты (Δ°C) (`delta_temperature`) | **✅** | ❌ | ❌ | ❌ | ❌ | ❌ | unit-convertor | | Размерностный анализ (м / с = м/с) (`dimensional_analysis`) | **✅** | ❌ | ❌ | ❌ | ❌ | ❌ | unit-convertor | | Динамические СИ-префиксы (любая единица + префикс) (`dynamic_si_prefixes`) | **✅** | ❌ | **✅** | ❌ | ❌ | ❌ | unit-convertor, php-units-of-measure | | Равенство в разных единицах (`equality_across_units`) | **✅** | ❌ | ❌ | ❌ | ❌ | **✅** | unit-convertor, measurements | | Внешние каталоги единиц (`external_catalogs`) | **✅** | ❌ | ❌ | ❌ | ❌ | ❌ | unit-convertor | | Исторические единицы (`historical_units`) | **✅** | ❌ | ❌ | ❌ | ❌ | ❌ | unit-convertor | | Двоичные IEC-префиксы (KiB, MiB…) (`iec_prefixes`) | **✅** | **✅** | ❌ | ❌ | ❌ | ❌ | unit-convertor, jordanbrauer | | Неизменяемые величины (`immutable`) | **✅** | ❌ | **✅** | ❌ | ❌ | **✅** | unit-convertor, php-units-of-measure, measurements | | Проверка, известна ли единица (`is_defined`) | **✅** | **✅** | **✅** | ❌ | ❌ | ❌ | unit-convertor, jordanbrauer, php-units-of-measure | | JSON-сериализация и восстановление (`json_serialization`) | **✅** | ❌ | ❌ | ❌ | ❌ | ❌ | unit-convertor | | Список категорий (`list_categories`) | **✅** | **✅** | ❌ | ❌ | **✅** | ❌ | unit-convertor, jordanbrauer, cartalyst | | Список единиц категории (`list_units`) | **✅** | **✅** | **✅** | ❌ | **✅** | ❌ | unit-convertor, jordanbrauer, php-units-of-measure, cartalyst | | Локализованные названия (6 языков) (`localized_names`) | **✅** | ❌ | ❌ | ❌ | ❌ | ❌ | unit-convertor | | Разбор составной строки «5 ft 3 in» (`parse_compound`) | **✅** | ❌ | ❌ | ❌ | ❌ | ❌ | unit-convertor | | Разбор строки «5.5 km» (`parse_string`) | **✅** | ❌ | ❌ | ❌ | ❌ | ❌ | unit-convertor | | Форматирование по шаблону (`pattern_format`) | **✅** | ❌ | ❌ | **✅** | **✅** | ❌ | unit-convertor, crisu83, cartalyst | | Точные float-результаты без накопления ошибки (`precise_floats`) | **✅** | ❌ | **✅** | ❌ | ❌ | ❌ | unit-convertor, php-units-of-measure | | Округление результата (`rounding`) | **✅** | ❌ | ❌ | ❌ | ❌ | ❌ | unit-convertor | | Проверка совпадения размерностей (`same_dimension`) | **✅** | ❌ | **✅** | ❌ | ❌ | ❌ | unit-convertor, php-units-of-measure | | Умножение и деление на число (`scale_by_number`) | **✅** | ❌ | ❌ | ❌ | ❌ | **✅** | unit-convertor, measurements | | Признак единицы СИ (`si_flag`) | **✅** | **✅** | ❌ | ❌ | ❌ | ❌ | unit-convertor, jordanbrauer | | Значение прописью (`spellout`) | **✅** | ❌ | ❌ | ❌ | ❌ | ❌ | unit-convertor | | Перевод в базовую единицу (`to_base_unit`) | **✅** | ❌ | **✅** | ❌ | ❌ | **✅** | unit-convertor, php-units-of-measure, measurements | | Разложение в составную величину (`to_compound`) | **✅** | ❌ | ❌ | ❌ | ❌ | ❌ | unit-convertor | | Строковое представление (`to_string`) | **✅** | ❌ | **✅** | **✅** | ❌ | **✅** | unit-convertor, php-units-of-measure, crisu83, measurements | | Подсказки при опечатке в единице (`typo_suggestions`) | **✅** | ❌ | ❌ | ❌ | ❌ | ❌ | unit-convertor | | Алиасы единиц (`unit_aliases`) | **✅** | ❌ | **✅** | ❌ | ❌ | ❌ | unit-convertor, php-units-of-measure | | Удаление единицы из реестра (`unregister_unit`) | **✅** | **✅** | ❌ | ❌ | ❌ | ❌ | unit-convertor, jordanbrauer |

2. Правильность

Ответ каждой операции на эталонном входе сверен с эталоном (benchmarks/operations.php, относительная погрешность 1e-5). ❌ — пакет ответил неверно или упал: такой пакет не участвует в замерах этой операции. Прочерк — операции нет.

Метрикаunit-convertorjordanbrauerphp-units-of-measurecrisu83cartalystmeasurements🏆 Победитель
length_m_cm✅✅✅✅✅✅ничья
mass_kg_lb✅✅✅✅—✅ничья
temp_c_f✅✅✅❌✅✅unit-convertor, jordanbrauer, php-units-of-measure, cartalyst, measurements
speed_kmh_ms✅✅✅✅—✅ничья
area_m2_ft2✅✅✅✅—✅ничья
volume_l_gal✅✅✅✅—✅ничья
data_gb_mb✅✅—❌——unit-convertor, jordanbrauer
energy_kwh_j✅✅✅✅—✅ничья
pressure_bar_psi✅✅✅✅—✅ничья
time_h_s✅✅✅✅—✅ничья
angle_deg_rad✅✅✅✅—✅ничья
fuel_l100_mpg✅✅—❌—❌unit-convertor, jordanbrauer
add_km_m✅—✅✅—✅ничья
compare_km_m✅————✅ничья
Верных ответов14121110212unit-convertor

3. phplint

Синтаксис исходников (php-parallel-lint) и доля файлов со строгой типизацией.

Метрикаunit-convertorjordanbrauerphp-units-of-measurecrisu83cartalystmeasurements🏆 Победитель
Находок000000ничья
Файлов с declare(strict_types=1)100,0 %100,0 %0,0 %0,0 %0,0 %0,0 %unit-convertor, jordanbrauer

4. Psalm

Psalm с настройками гейта пакета (errorLevel 1, строгие бинарные операнды) по исходникам каждого пакета на его минимальной версии PHP; поиск неиспользуемого кода отключён для всех, так как тесты аналогов не входят в дистрибутив.

Метрикаunit-convertorjordanbrauerphp-units-of-measurecrisu83cartalystmeasurements🏆 Победитель
Находок01 1882145583673unit-convertor
Находок на 1000 строк кода0,00125,71120,9034,68105,20174,76unit-convertor
errorLevel Psalm в репозитории (1 — строже всего)1—————unit-convertor
Подавленных ошибок в baseline0—————unit-convertor

5. PHPStan

PHPStan уровня max с настройками гейта пакета по исходникам каждого пакета на его минимальной версии PHP.

Метрикаunit-convertorjordanbrauerphp-units-of-measurecrisu83cartalystmeasurements🏆 Победитель
Находок02561414052401unit-convertor
Находок на 1000 строк кода0,0027,0979,6625,2265,91104,13unit-convertor
Уровень PHPStan в репозиторииmax—————unit-convertor
Подавленных ошибок в baseline0—————unit-convertor

6. PHPMD

PHPMD с набором правил гейта пакета (phpmd.xml).

Метрикаunit-convertorjordanbrauerphp-units-of-measurecrisu83cartalystmeasurements🏆 Победитель
Находок05144211unit-convertor
Находок на 1000 строк кода0,000,537,912,522,532,86unit-convertor

7. PHPCS

PHPCS со стандартом гейта пакета (phpcs.xml.dist).

Метрикаunit-convertorjordanbrauerphp-units-of-measurecrisu83cartalystmeasurements🏆 Победитель
Находок08595625943 783unit-convertor
Находок на 1000 строк кода0,0090,9031,64163,305,07982,34unit-convertor
Конфигурация стиля кода в репозитории✅✅❌❌❌❌unit-convertor, jordanbrauer

8. Rector

Rector с наборами гейта пакета (PHP 8.1, dead code, code quality, type declarations): файлов, которые он изменил бы.

Метрикаunit-convertorjordanbrauerphp-units-of-measurecrisu83cartalystmeasurements🏆 Победитель
Находок0231149737unit-convertor
Находок на 1000 строк кода0,002,436,2130,908,879,61unit-convertor
Rector в репозитории✅❌❌❌❌❌unit-convertor

9. Deptrac

Правила архитектурных слоёв зависят от проекта, поэтому сравнивается наличие контроля слоёв.

Метрикаunit-convertorjordanbrauerphp-units-of-measurecrisu83cartalystmeasurements🏆 Победитель
Правила архитектурных слоёв (Deptrac) в репозитории✅❌❌❌❌❌unit-convertor

10. Мутационное тестирование

MSI измерен прогоном Infection у собственного пакета; у аналогов — наличие мутационного тестирования.

Метрикаunit-convertorjordanbrauerphp-units-of-measurecrisu83cartalystmeasurements🏆 Победитель
Infection в репозитории✅❌❌❌❌❌unit-convertor
MSI100,00 %—————unit-convertor

11. Безопасность

Пробы безопасности исполняются вызовом API каждого пакета (benchmarks/capabilities.php); вызовы и @ подсчитаны по токенам PHP в исходниках (методы и комментарии не учитываются), уязвимости — composer audit по установке пакета. Прочерк — проба неприменима (у пакета нет разбора строк или файлов локалей).

Метрикаunit-convertorjordanbrauerphp-units-of-measurecrisu83cartalystmeasurements🏆 Победитель
NAN на входе отклоняется исключением✅❌❌❌❌❌unit-convertor
INF на входе отклоняется исключением✅❌❌❌❌❌unit-convertor
Неизвестная единица — типизированное исключение пакета✅❌✅✅✅❌unit-convertor, php-units-of-measure, crisu83, cartalyst
Код локали не выходит за каталог данных (../)✅—————unit-convertor
Длина разбираемой строки ограничена✅—————unit-convertor
Опасных вызовов (eval, unserialize, exec, system…)010000unit-convertor, php-units-of-measure, crisu83, cartalyst, measurements
Подавлений ошибок оператором @000000ничья
Известных уязвимостей в дереве зависимостей (composer audit)000000ничья
Заброшенных пакетов в дереве зависимостей000000ничья

Соответствие стандартам безопасности

Каждая отметка выведена из проб и измерений выше и из клона репозитория, а не заполнена вручную. Прочерк — требование к пакету неприменимо (например, у пакета нет разбора строк или файлов локалей).

Стандарт / требованиеunit-convertorjordanbrauerphp-units-of-measurecrisu83cartalystmeasurements🏆 Победитель
CWE-20: проверка входа — NAN и INF отклоняются✅❌❌❌❌❌unit-convertor
CWE-755: ошибки ввода — типизированные исключения, а не PHP-ошибки✅❌✅✅✅❌unit-convertor, php-units-of-measure, crisu83, cartalyst
CWE-22: нет обхода каталогов через код локали✅—————unit-convertor
CWE-400: ограничение ресурсов — лимит длины входной строки✅—————unit-convertor
CWE-95 / CWE-502 / CWE-78: нет eval, unserialize, запуска команд✅❌✅✅✅✅unit-convertor, php-units-of-measure, crisu83, cartalyst, measurements
CWE-391: ошибки не подавляются оператором @✅✅✅✅✅✅ничья
CWE-1339: доступна произвольная точность вещественных чисел✅❌❌❌❌❌unit-convertor
OWASP Top 10 A06:2021: нет уязвимых и заброшенных компонентов✅✅✅✅✅✅ничья
OpenSSF Scorecard «Security-Policy»: есть SECURITY.md✅✅❌❌❌❌unit-convertor, jordanbrauer
OpenSSF Scorecard «Maintained»: коммиты за последние 90 дней✅❌✅❌❌❌unit-convertor, php-units-of-measure
OpenSSF Scorecard «CI-Tests»: тесты в CI✅✅✅✅✅✅ничья
OpenSSF Scorecard «SAST»: статический анализ в репозитории✅❌❌❌❌❌unit-convertor
OpenSSF Scorecard «Dependency-Update-Tool»: Dependabot/Renovate✅❌❌❌❌❌unit-convertor
OpenSSF Scorecard «License»: лицензия в репозитории✅✅✅✅✅✅ничья

12. Потребление памяти

Память самой библиотеки, КБ: прирост пика от точки до подключения автозагрузчика до конца 20 000 вызовов операции. Прочерк — у пакета нет такой возможности или ответ неверен.

Метрикаunit-convertorjordanbrauerphp-units-of-measurecrisu83cartalystmeasurements🏆 Победитель
length_m_cm514,615 883,9207,1207,1483,3207,1php-units-of-measure, crisu83, measurements
mass_kg_lb514,615 884,4207,1207,1—207,1php-units-of-measure, crisu83, measurements
temp_c_f514,615 885,4207,1—483,3207,1php-units-of-measure, measurements
speed_kmh_ms514,615 885,0207,1207,1—207,1php-units-of-measure, crisu83, measurements
area_m2_ft2514,615 885,1207,1207,1—207,1php-units-of-measure, crisu83, measurements
volume_l_gal514,615 887,8207,1207,1—207,1php-units-of-measure, crisu83, measurements
data_gb_mb514,615 884,5————unit-convertor
energy_kwh_j514,615 886,1207,1207,1—207,1php-units-of-measure, crisu83, measurements
pressure_bar_psi514,615 884,9207,1207,1—207,1php-units-of-measure, crisu83, measurements
time_h_s514,615 885,8207,1207,1—207,1php-units-of-measure, crisu83, measurements
angle_deg_rad514,615 885,1207,1207,1—207,1php-units-of-measure, crisu83, measurements
fuel_l100_mpg514,615 885,0————unit-convertor
add_km_m514,6—207,1207,1—207,1php-units-of-measure, crisu83, measurements
compare_km_m514,6————207,1measurements

13. Утечки памяти

Рост удерживаемой памяти после прогрева на 50 000 вызовов, байт (0 — утечек нет).

Метрикаunit-convertorjordanbrauerphp-units-of-measurecrisu83cartalystmeasurements🏆 Победитель
length_m_cm038 196 7360000unit-convertor, php-units-of-measure, crisu83, cartalyst, measurements
mass_kg_lb038 194 86400—0unit-convertor, php-units-of-measure, crisu83, measurements
temp_c_f038 196 7440—00unit-convertor, php-units-of-measure, cartalyst, measurements
speed_kmh_ms038 195 85600—0unit-convertor, php-units-of-measure, crisu83, measurements
area_m2_ft2038 197 90400—0unit-convertor, php-units-of-measure, crisu83, measurements
volume_l_gal038 200 12800—0unit-convertor, php-units-of-measure, crisu83, measurements
data_gb_mb038 197 080————unit-convertor
energy_kwh_j038 196 86400—0unit-convertor, php-units-of-measure, crisu83, measurements
pressure_bar_psi038 198 55200—0unit-convertor, php-units-of-measure, crisu83, measurements
time_h_s038 195 99200—0unit-convertor, php-units-of-measure, crisu83, measurements
angle_deg_rad038 200 50400—0unit-convertor, php-units-of-measure, crisu83, measurements
fuel_l100_mpg038 197 952————unit-convertor
add_km_m0—00—0ничья
compare_km_m0————0ничья

14. Производительность

Время серии из 20 000 вызовов, мс (лучшее из 5 серий). Прочерк — у пакета нет такой возможности или ответ неверен. Разница меньше 3 % лежит в пределах разброса повторных замеров: такие пакеты делят победу.

Метрикаunit-convertorjordanbrauerphp-units-of-measurecrisu83cartalystmeasurements🏆 Победитель
length_m_cm4,4295,2616,628,1771,5918,04unit-convertor
mass_kg_lb4,31110,1515,888,31—18,00unit-convertor
temp_c_f4,36121,0416,12—69,3717,77unit-convertor
speed_kmh_ms4,42117,0115,807,89—16,69unit-convertor
area_m2_ft24,43102,0016,077,93—18,30unit-convertor
volume_l_gal4,49106,7016,117,92—18,20unit-convertor
data_gb_mb4,40150,33————unit-convertor
energy_kwh_j4,31138,2016,077,89—16,51unit-convertor
pressure_bar_psi4,22132,1516,248,43—18,59unit-convertor
time_h_s4,27135,4116,088,41—16,90unit-convertor
angle_deg_rad4,38121,9616,448,22—18,89unit-convertor
fuel_l100_mpg7,28153,39————unit-convertor
add_km_m46,90—40,2912,40—36,95crisu83
compare_km_m28,09————49,31unit-convertor

15. Качество

Практики сняты с клона исходного репозитория каждого пакета; покрытие измерено только у собственного пакета (у аналогов прочерк — не измерялось).

Метрикаunit-convertorjordanbrauerphp-units-of-measurecrisu83cartalystmeasurements🏆 Победитель
Файлов тестов28018510unit-convertor
Покрытие тестами (строки и методы)100,00 %—————unit-convertor
Конвейеров CI311112unit-convertor
Журнал изменений✅✅✅❌✅❌unit-convertor, jordanbrauer, php-units-of-measure, cartalyst
Последний коммит2026-10-012023-08-232026-09-262016-05-182025-02-282022-02-11unit-convertor

Воспроизвести: php benchmarks/install.php && php benchmarks/compare.php && php benchmarks/analysis.php && php benchmarks/generate.php.

Честно о плюсах и минусах

Плюсы:

  • функциональный суперсет всех сравниваемых аналогов вместе взятых (см. таблицу выше: единственный со строковым парсингом, размерностным анализом, дельта-температурами, локализацией и внешними справочниками);
  • самая быстрая конверсия среди аналогов — в 1.8–35 раз быстрее в каждой измеренной паре единиц, сравнение величин — в 1.7 раза быстрее;
  • отклоняет NAN/INF на входе и переполнение в арифметике величин; ни один из аналогов NAN/INF не отклоняет (см. таблицу безопасности);
  • 100 % покрытие строк и 100 % MSI мутационного тестирования; PHPStan max + strict, Psalm level 1, Deptrac-слои;
  • физическая корректность там, где аналоги молча считают неверно (линейные «температуры» crisu83, отсутствие offset у cartalyst).

Минусы:

  • пакет моложе и менее распространён, чем аналоги (меньше звёзд, установок и практики сообщества);
  • рабочий footprint (~515 КБ против ~207 КБ у лёгких аналогов) — цена 99 категорий, полного индекса кодов и pair-кэша; если нужна пара конверсий длины в микросервисе с жёстким лимитом памяти, легковес может подойти лучше;
  • сложение величин (add_km_m) медленнее, чем у crisu83, measurements и php-units-of-measure: Quantity иммутабелен и на каждую операцию создаёт новый объект с проверкой совместимости и аффинных шкал, тогда как crisu83 мутирует один объект. Иммутабельность и запрет некорректной арифметики температур — сознательный выбор в пользу корректности;
  • режим произвольной точности тянет cloud-castle/match (ext-bcmath).

Когда и где применять

  • E-commerce, логистика, доставка — габариты и вес в разных системах, «5 ft 3 in» из американских карточек товара, локализованный вывод.
  • IoT и телеметрия — датчики в смешанных единицах, температурные дельты без физических ошибок, mkЗв/ч и Бк/м³ для радиометрии.
  • Финтех и биллинг ресурсов — convertPrecise() для тарификации энергии (кВт·ч ↔ Дж) без накопления float-погрешности.
  • Медицина и лаборатории — мг/дл, ммоль/л, °dH, МЕ ферментов; строгие исключения вместо тихих ошибок.
  • Автомобильные сервисы — расход л/100км ↔ mpg (US/UK), крутящий момент Н·м ↔ lbf·ft, давление шин.
  • Контент и переводы — 6 локалей с плюрализацией, русские исторические меры для образовательных и музейных проектов.
  • Когда не стоит: нужен неизменяемый набор из двух-трёх фиксированных коэффициентов в скрипте на 20 строк — хватит и умножения на константу.

Разработка

composer install
composer check    # линтеры + статический анализ + тесты
composer fix      # автоисправления (Rector, PHP CS Fixer, PHPCBF)
composer ci       # полный CI-пайплайн локально
composer infection            # мутационное тестирование (MSI 100%)
composer docs:build           # пересборка сравнительных таблиц
php tools/build-index.php     # пересборка индекса данных

Полный список команд с описаниями: composer run-script --list.

Документация

Лицензия

MIT © CloudCastle (alex-4-17@yandex.ru)

🇷🇺 Русский · 🇬🇧 English · 🇩🇪 Deutsch · 🇫🇷 Français · 🇪🇸 Español · 🇮🇹 Italiano