matriphe/iso-639
matriphe/iso-639 is a lightweight Laravel/PHP package that provides a complete list of ISO 639 language codes. Look up language names by code (or code by name) and use the bundled facade for quick, consistent language identification in your apps.
Install the package with Composer; there is no service provider, facade, or config file to publish — it is a single plain-PHP class.
composer require matriphe/iso-639
First thing to read is the one class that matters: Matriphe\ISO639\Lang. The entire API is a handful of static methods backed by two in-memory arrays (code → name and name → code), so skim the source once and you know the whole package.
The canonical first use case is turning a stored locale code into a human-readable label:
use Matriphe\ISO639\Lang;
Lang::getName('en'); // "English"
Lang::getName('id'); // "Indonesian"
Lang::getNames(); // ['en' => 'English', 'id' => 'Indonesian', ...]
That is genuinely the whole onboarding — wire it into one Blade template or one model accessor and you have captured 90% of what the package does.
Model accessor for stored locale codes. Most apps already store an ISO-639-1 code (users.locale, posts.language); expose the label without a join table:
public function getLanguageLabelAttribute(): string
{
return Lang::getName($this->language) ?? $this->language;
}
Blade partial for locale switchers. Because the full map is a static array, you can render a dropdown inline with no query:
<select name="locale">
@foreach (\Matriphe\ISO639\Lang::getNames() as $code => $name)
<option value="{{ $code }}" @selected($code === app()->getLocale())>
{{ $name }}
</option>
@endforeach
</select>
Validation rule. ISO-639-1 codes are a fixed set, so in: validation backed by the package is more honest than a regex:
use Illuminate\Validation\Rule;
$request->validate([
'locale' => ['required', 'string', Rule::in(array_keys(Lang::getNames()))],
]);
API resources. Normalise the payload so clients never have to interpret codes themselves:
return [
'locale' => $this->locale,
'locale_name' => Lang::getName($this->locale),
];
Reverse lookup for forms. When an admin types "French" instead of fr, Lang::getCode('French') (or the equivalent reverse method in the class) closes the loop. Keep a small LanguageResolver wrapper if you use this in more than one place, so you can swap implementations in tests.
Normalise before you call. Because the package is a plain lookup table, the defensive input handling belongs on your side of the boundary — one helper beats scattering strtolower() and explode('-') at every call site:
function languageLabel(?string $tag): ?string
{
$primary = strtolower(trim(explode('-', (string) $tag)[0]));
return $primary === '' ? null : Lang::getName($primary);
}
en-US, pt-BR, zh-Hans will not resolve, because the package has no notion of regions or scripts. If you accept BCP-47 tags, split on - first and look up the primary subtag, or accept the null and fall back to the raw value.en, zh); names are English-cased ("English", "Mandarin Chinese"). Do not assume Lang::getName('EN') works — normalise with strtolower() before calling.'' (or a value whose primary subtag resolves to nothing) returns null rather than blowing up on a lookup. This is the release that makes the accessor pattern above safe against null/blank columns — but if you are pinned below v2.0.10, guard the call yourself.Lang::getName(...) so a data correction does not turn into a red build. If labels are exported into stored data or downstream systems, pin the minor version and review the changelog before bumping.src/Lang.php and confirm the exact signatures rather than trusting blog snippets — different forks of php-iso-639 use getName/getLanguage/getNames inconsistently.null is possible. Unknown or unsupported codes return null rather than throwing. Always coalesce (?? $code) when rendering to end users so a missing language does not blank a profile page.Lang. In tests, either assert against real values (Lang::getName('fr') === 'French') or wrap the package behind a small interface so you can fake it — the latter is worth doing the moment you need to test a language-switcher feature.composer update. Treat it as a lookup table, not as infrastructure."English" — reach for a CLDR/locale package or symfony/intl instead, and use this library purely for the canonical English label and code validation.Lang, override the relevant method, and bind your subclass in a container alias. A subclass also lets you pin a label you disagree with (say, a specific Bihari spelling) without forking the package.How can I help you explore Laravel packages today?