Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Iso 639 Laravel Package

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.

View on GitHub
Deep Wiki
Context7

Getting Started

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.

Implementation Patterns

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);
}

Gotchas and Tips

  • This is ISO-639-1 only — two-letter codes. 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.
  • Case sensitivity. Codes are lowercase (en, zh); names are English-cased ("English", "Mandarin Chinese"). Do not assume Lang::getName('EN') works — normalise with strtolower() before calling.
  • Empty codes are handled as of v2.0.10. The "Handle empty hashmap" fix plus the new empty-code test case mean passing '' (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.
  • Label data gets corrected in patch releases. v2.0.10 revised the Bihari entry. Never hardcode an expected name literal in tests or fixtures — assert on codes, or compare against 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.
  • The method names are not a stable public contract. It is one small class from a low-traffic package (50 stars, 0 dependents). Before relying on a specific method name in production, open src/Lang.php and confirm the exact signatures rather than trusting blog snippets — different forks of php-iso-639 use getName/getLanguage/getNames inconsistently.
  • Return 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.
  • Static methods make mocking awkward. You cannot dependency-inject 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.
  • No Laravel auto-discovery, so nothing to configure. That is a feature here: it also means there is no config to override, no cache key to clear, and nothing to break on composer update. Treat it as a lookup table, not as infrastructure.
  • The array is loaded per process, not per request. In Octane or long-running workers it is effectively free after the first call; no caching layer is warranted. In classic PHP-FPM each request rebuilds it, but with ~180 entries that cost is negligible.
  • Do not confuse this with display localisation. The names returned are always English. If your UI is in Japanese and you need "英語", this package gives you "English" — reach for a CLDR/locale package or symfony/intl instead, and use this library purely for the canonical English label and code validation.
  • Extension point is the array itself. If you need to add a language or override a label, there is no config hook — subclass 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.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels