php-standard-library/locale
PHP Standard Library Locale component providing locale-aware formatting and parsing utilities. Helps handle language/region settings, localized dates, numbers, and other internationalization tasks in PHP apps with a lightweight, straightforward API.
Installation
composer require php-standard-library/locale
No additional configuration is required for basic usage.
First Use Case: Validate and Normalize a Locale
use PhpStandardLibrary\Locale\Locale;
// Validate and parse a locale string
$localeString = 'en-US'; // User input or request header
$locale = Locale::fromString($localeString);
if ($locale->isValid()) {
$normalized = $locale->toString(); // 'en_US'
$language = $locale->getLanguage(); // 'en'
$region = $locale->getRegion(); // 'US'
} else {
// Handle invalid locale (e.g., fallback or error)
}
Where to Look First
PhpStandardLibrary\Locale\Locale for parsing, validation, and normalization.Locale::isValid(string $locale) – Check if a string is a valid locale.Locale::fromString(string $locale) – Parse a string into a Locale object (throws on invalid input).Locale::normalize(string $locale) – Convert to a standardized format (e.g., en-us → en_US).getLanguage(), getRegion(), getScript(), getVariant() – Extract components of a locale.Parse and validate locale from headers, cookies, or form inputs:
use PhpStandardLibrary\Locale\Locale;
public function handle(Request $request, Closure $next) {
$localeString = $request->header('Accept-Language', config('app.locale'));
$locale = Locale::fromString($localeString);
// Set the normalized locale for the request
app()->setLocale($locale->toString());
return $next($request);
}
Replace manual regex validation with type-safe checks:
use PhpStandardLibrary\Locale\Locale;
use Illuminate\Validation\Rule;
public function rules() {
return [
'locale' => [
'required',
function (string $attribute, mixed $value, Closure $fail) {
if (!Locale::isValid($value)) {
$fail('The :attribute must be a valid locale (e.g., en_US).');
}
},
],
];
}
Enforce locale types in model attributes:
use PhpStandardLibrary\Locale\Locale;
class User extends Model {
protected $casts = [
'locale' => Locale::class, // Automatically parse/validate on set
];
// Accessor for type safety
public function getLocaleAttribute(string $value): Locale {
return Locale::fromString($value);
}
// Mutator to ensure validation
public function setLocaleAttribute(string $value) {
$this->attributes['locale'] = Locale::normalize($value);
}
}
Validate locale fields in API payloads:
use PhpStandardLibrary\Locale\Locale;
public function validated() {
$validated = $this->validate([
'user_locale' => [
'sometimes',
function (string $value) {
return Locale::isValid($value);
},
],
]);
return $validated;
}
Normalize locales before passing to Laravel’s trans() or third-party libraries:
use PhpStandardLibrary\Locale\Locale;
$userLocale = Locale::fromString($request->user()->locale);
$translated = trans('messages.welcome', [], null, $userLocale->toString());
Use locale components for region-specific formatting (e.g., dates, numbers):
use PhpStandardLibrary\Locale\Locale;
use Carbon\Carbon;
$locale = Locale::fromString('fr_FR');
$date = Carbon::now()->setLocale($locale->getLanguage());
// Or for number formatting (with a library like `number-formatter`)
$formatter = new \NumberFormatter($locale->toString(), \NumberFormatter::DECIMAL);
Service Provider Bootstrapping
Normalize the app’s default locale in AppServiceProvider:
public function boot() {
$defaultLocale = config('app.locale');
config(['app.locale' => Locale::normalize($defaultLocale)]);
}
Middleware for Locale Resolution Create a middleware to resolve and set the locale for each request:
namespace App\Http\Middleware;
use PhpStandardLibrary\Locale\Locale;
use Closure;
class SetLocale {
public function handle($request, Closure $next) {
$locale = Locale::fromString(
$request->header('X-Locale', $request->cookie('locale', config('app.locale')))
);
app()->setLocale($locale->toString());
return $next($request);
}
}
Register it in app/Http/Kernel.php:
protected $middleware = [
\App\Http\Middleware\SetLocale::class,
];
Custom Validation Rules Create a reusable validation rule:
namespace App\Rules;
use PhpStandardLibrary\Locale\Locale;
use Illuminate\Contracts\Validation\Rule;
class ValidLocale implements Rule {
public function passes($attribute, $value) {
return Locale::isValid($value);
}
public function message() {
return 'The :attribute must be a valid locale (e.g., en_US).';
}
}
Usage:
$validator->rule(new ValidLocale());
Testing Locales Use the package to assert locale handling in tests:
use PhpStandardLibrary\Locale\Locale;
use Tests\TestCase;
class LocaleTest extends TestCase {
public function testLocaleValidation() {
$this->assertTrue(Locale::isValid('en_US'));
$this->assertFalse(Locale::isValid('invalid'));
}
public function testLocaleNormalization() {
$this->assertEquals('en_US', Locale::normalize('en-us'));
$this->assertEquals('fr', Locale::normalize('fr'));
}
}
Locale-Aware API Responses Attach the resolved locale to API responses:
return response()->json([
'data' => $data,
'locale' => app()->getLocale(), // Normalized by middleware
]);
Case Sensitivity in Locale Strings
en-us → EN_US → en_US).Locale::normalize() or Locale::fromString() to avoid case-related bugs.'en-us' may fail validation if not normalized first.Invalid Locale Handling
Locale::fromString() throws an exception on invalid input. Use Locale::isValid() for silent checks.$locale = Locale::isValid($input) ? Locale::fromString($input) : Locale::fromString('en');
Private and Extended Locale Tags
sr-Latn-RS or und).$customLocales = ['und', 'sr-Latn-RS'];
if (in_array($localeString, $customLocales) || Locale::isValid($localeString)) {
// Proceed
}
Performance with Bulk Operations
$locales = collect($rawLocales)->map(function ($locale) {
return cache()->remember("locale.{$locale}", now()->addHours(1), function () use ($locale) {
return Locale::normalize($locale);
});
});
Database Storage
en_US) in the database to avoid inconsistencies.en-us) may not match stored values if not normalized.
How can I help you explore Laravel packages today?