Installation:
composer require webpatser/laravel-countries
Update config/app.php to include:
'providers' => [
Webpatser\Countries\CountriesServiceProvider::class,
],
'aliases' => [
'Countries' => Webpatser\Countries\CountriesFacade::class,
]
Publish Configuration (Optional):
php artisan config:publish webpatser/laravel-countries
(Only needed if customizing the countries table name.)
Run Migration:
php artisan countries:migration
php artisan migrate
First Use Case: Fetch a country by ISO code:
$country = Countries::get('US');
dd($country->name); // Outputs: "United States"
Retrieving Country Data:
// By ISO code (2-letter)
$country = Countries::get('US');
// By ISO 3166-1 numeric code
$country = Countries::getByNumeric('840');
// All countries (as collection)
$allCountries = Countries::all();
Filtering Countries:
// By continent
$europeanCountries = Countries::where('continent', 'Europe')->get();
// By currency
$euroCountries = Countries::where('currency', 'EUR')->get();
Integration with Eloquent Models:
Add a country_id field to a model (e.g., User) and use the facade:
// In a User model
public function country()
{
return $this->belongsTo(Country::class);
}
// Usage
$user = User::find(1);
$countryName = $user->country->name; // "Canada" if country_id=124
Form Validation:
use Webpatser\Countries\Rules\Country;
$request->validate([
'country_code' => ['required', new Country],
]);
Localization: Publish translations (if needed):
php artisan vendor:publish --provider="Webpatser\Countries\CountriesServiceProvider" --tag=lang
Then use:
$countryName = __("countries.US"); // "United States" (if translated)
Custom Queries:
Extend the Country model to add scopes:
// In app/Providers/AppServiceProvider.php
use Webpatser\Countries\Models\Country;
Country::addGlobalScope('Active', function (Builder $builder) {
$builder->where('active', 1);
});
API Responses: Format country data for APIs:
return response()->json([
'country' => Countries::get('US')->toArray(),
]);
Caching: Cache country data for performance:
$countries = Cache::remember('all-countries', now()->addDays(7), function () {
return Countries::all();
});
Outdated Data:
SSD for South Sudan) or currencies (e.g., EUR for new EU members) manually if critical.countries table with a custom migration or use a modern alternative like league/iso3166.Missing ISO 3166-2 Codes:
Facade vs. Model Direct Access:
Countries::get('US') for simplicity, but access the underlying Country model directly for complex queries:
$country = \Webpatser\Countries\Models\Country::where('iso', 'US')->first();
Migration Conflicts:
countries table already exists, drop it first or use:
php artisan countries:migration --force
Check Database Data:
php artisan tinker
>>> \Webpatser\Countries\Models\Country::all()->count(); // Should return 249 (as of 2015)
Validate ISO Codes:
if (!Countries::exists('XX')) { // 'XX' = invalid code
abort(400, 'Invalid country code');
}
Override Defaults: Publish and modify the config:
php artisan config:publish webpatser/laravel-countries
Then update config/countries.php (e.g., change table or model values).
Add Custom Fields:
Extend the Country model:
// app/Models/Country.php
namespace App\Models;
use Webpatser\Countries\Models\Country as BaseCountry;
class Country extends BaseCountry
{
protected $appends = ['population_density'];
public function getPopulationDensityAttribute()
{
return $this->population / ($this->area ?? 1);
}
}
Hook into Bootstrapping:
Add logic in CountriesServiceProvider:
// app/Providers/CountriesServiceProvider.php
public function boot()
{
\Webpatser\Countries\Models\Country::created(function ($country) {
// Log or notify when countries are added
});
}
Replace the Data Source:
Override the getCountries() method in the service provider to fetch from an external API:
public function getCountries()
{
$response = Http::get('https://restcountries.com/v3.1/all');
return collect($response->json())->map(fn ($data) => [
'iso' => $data['cca2'],
'name' => $data['name']['common'],
// ... map other fields
]);
}
$users = User::with('country')->get();
$country = Countries::select('name', 'iso', 'currency')->get('US');
How can I help you explore Laravel packages today?