Data Unit Converter — PHP source
Convert between digital data units - B, KB/KiB, MB/MiB, GB/GiB, TB/TiB. Switch between decimal (1000) and binary (1024) bases, runs entirely in your browser.
This is the PHP implementation — the same logic the interactive tool runs, in a shareable, citable form.
<?php
/**
* data-unit-converter — polyglot showcase port (PHP).
*
* Pure digital-data unit conversion for the Data Unit Converter tool on
* CosmoDev (dev.cosmolabs.org). Ported from the canonical TypeScript source at
* src/lib/dataUnits.ts so the tool page can display the same logic across six
* languages.
*
* Supports B, KB/KiB, MB/MiB, GB/GiB, TB/TiB. Decimal base = 1000 (KB, MB, GB,
* TB); binary base = 1024 (KiB, MiB, GiB, TiB). Pure + deterministic.
* convert_data returns NAN for non-finite input, unknown units, or an invalid
* base — it never throws.
*
* Self-contained: standard library only, no external dependencies (no Composer
* packages).
*
* License/usage: display source — part of CosmoDev's polyglot tool pages.
*/
namespace CosmoDev\DataUnitConverter;
/**
* Units available under each base, ordered smallest (B) to largest. The UI
* uses this to populate the per-base unit pickers. Keys are the numeric base.
*/
const UNITS = [
1000 => ['B', 'KB', 'MB', 'GB', 'TB'],
1024 => ['B', 'KiB', 'MiB', 'GiB', 'TiB'],
];
/**
* Power-of-base rank for each unit: B is rank 0, each prefix step adds 1.
* KB and KiB are both rank 1 — the unit picks the rank, the base decides
* whether a rank means ×1000 or ×1024.
*/
const EXPONENT = [
'B' => 0,
'KB' => 1, 'MB' => 2, 'GB' => 3, 'TB' => 4,
'KiB' => 1, 'MiB' => 2, 'GiB' => 3, 'TiB' => 4,
];
/**
* Convert a value between two digital-data units under the given base.
*
* Strategy: reduce to bytes via value × base^fromExp, then divide by
* base^toExp. Returns NAN for non-finite input, unknown units, or an invalid
* base — never throws (mirrors the TypeScript contract).
*
* @param float|int|string $value Magnitude to convert. Loose typing lets us
* accept numeric strings the way the JS
* caller would; non-numeric becomes NAN.
* @param string $fromUnit Source unit symbol.
* @param string $toUnit Target unit symbol.
* @param int $base Conversion base: 1000 or 1024.
*
* @return float Converted value, or NAN on invalid input.
*/
function convert_data($value, string $fromUnit, string $toUnit, int $base): float
{
// Coerce incoming scalars to float; reject anything that isn't numeric.
if (!is_numeric($value)) {
return NAN;
}
$value = (float) $value;
// Reject Inf/NaN early so they don't propagate through the multiplication.
if (!is_finite($value)) {
return NAN;
}
// Only the two canonical bases are valid; anything else is a caller bug.
if ($base !== 1000 && $base !== 1024) {
return NAN;
}
// Unknown unit symbols index into null; treat as invalid. The ?? NAN
// default preserves the TS dictionary-miss behavior.
$fromExp = EXPONENT[$fromUnit] ?? null;
$toExp = EXPONENT[$toUnit] ?? null;
if ($fromExp === null || $toExp === null) {
return NAN;
}
return ($value * $base ** $fromExp) / $base ** $toExp;
}
Also available in 13 other languages
Every CosmoDev tool ships its pure logic in TypeScript (web) and Go (CLI), with authored implementations in a dozen-plus languages — the same contract, ported. Compare all languages side by side →