Weave Code
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

Addressing Laravel Package

commerceguys/addressing

Addressing library for handling international postal addresses. Provides country and subdivision data, address formats, validation, and formatting utilities. Useful for commerce, shipping, and any app that needs correct, locale-aware addresses worldwide.

Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require commerceguys/addressing
    

    Add to composer.json if using a monorepo or strict dependencies.

  2. First Use Case: Parsing an Address

    use CommerceGuys\Addressing\Address;
    use CommerceGuys\Addressing\AddressFormatter;
    use CommerceGuys\Addressing\AddressParser;
    use CommerceGuys\Addressing\Country\CountryRepository;
    
    // Initialize dependencies
    $countryRepository = new CountryRepository();
    $addressParser = new AddressParser($countryRepository);
    $addressFormatter = new AddressFormatter($countryRepository);
    
    // Parse a raw address string
    $address = $addressParser->parse('1600 Amphitheatre Parkway, Mountain View, CA 94043, USA');
    
  3. Where to Look First

    • Documentation: Official Docs (if available).
    • CLDR Data: The package relies on Unicode CLDR for localization. Verify your vendor/commerceguys/addressing/src/Resources/cldr directory is intact.
    • Country Repository: Explore CountryRepository for supported countries and validation rules.

Implementation Patterns

Core Workflows

1. Address Parsing and Validation

// Parse with strict validation (throws exceptions on errors)
$address = $addressParser->parseStrict('Invalid Address', 'US');

// Parse with relaxed validation (returns partial data)
$address = $addressParser->parse('123 Main St', 'US');

2. Formatting Addresses for Display

// Format for a specific locale (e.g., 'en_US')
$formatted = $addressFormatter->format($address, 'en_US');

// Customize formatting rules
$formatter = new AddressFormatter($countryRepository, [
    'default' => AddressFormatter::STYLE_FULL,
    'US' => AddressFormatter::STYLE_POSTAL,
]);

3. Working with Subdivisions (States, Provinces)

// Get all subdivisions for a country (e.g., US states)
$subdivisions = $countryRepository->getCountry('US')->getSubdivisions();

// Parse a subdivision code
$subdivision = $countryRepository->getSubdivision('US-CA');

4. Integration with Laravel Requests

// Parse address from request input
$rawAddress = request()->input('address');
$address = $addressParser->parse($rawAddress, request()->input('country_code'));

// Validate parsed address
$validator = Validator::make(['address' => $address], [
    'address' => ['required', 'address:US'], // Custom rule for validation
]);

5. Localization and i18n

// Load a specific locale (e.g., German)
$countryRepository->loadCountry('DE', 'de_DE');

// Format address in German
$formattedDE = $addressFormatter->format($address, 'de_DE');

6. Custom Address Fields

// Extend Address class for custom fields (e.g., 'apartment')
class CustomAddress extends Address {
    public $apartment;
}

// Parse with custom fields
$address = $addressParser->parse('1600 Amphitheatre Parkway #100, Mountain View, CA 94043, USA', 'US');
$address->apartment = '100'; // Manually set if not parsed

Integration Tips

Laravel Service Provider

// config/app.php
'providers' => [
    App\Providers\AddressingServiceProvider::class,
],

// app/Providers/AddressingServiceProvider.php
public function register() {
    $this->app->singleton(CountryRepository::class, function ($app) {
        $repository = new CountryRepository();
        $repository->loadCountry('US', 'en_US'); // Preload common countries
        return $repository;
    });
}

Eloquent Model Casting

// app/Models/User.php
protected $casts = [
    'address' => AddressCast::class, // Custom cast for Address objects
];

API Responses

// Format address for API responses
return response()->json([
    'address' => $addressFormatter->format($user->address, 'en_US'),
]);

Gotchas and Tips

Pitfalls

  1. CLDR Data Loading

    • Issue: Missing or corrupted CLDR data can break parsing/formatting.
    • Fix: Ensure vendor/commerceguys/addressing/src/Resources/cldr is not modified or deleted. Reinstall the package if needed.
    • Tip: Preload countries in your service provider to avoid runtime loading delays:
      $repository->loadCountry('US', 'en_US');
      $repository->loadCountry('DE', 'de_DE');
      
  2. Strict vs. Relaxed Parsing

    • Issue: parseStrict() throws exceptions for invalid addresses, while parse() returns partial data. Misusing these can lead to silent failures.
    • Tip: Use parseStrict() in critical paths (e.g., billing) and parse() for user-friendly forms.
  3. Subdivision Codes

    • Issue: Subdivision codes (e.g., US-CA) are case-sensitive and must match CLDR data exactly.
    • Tip: Normalize codes before parsing:
      $subdivisionCode = strtoupper(request()->input('state'));
      
  4. Locale Fallbacks

    • Issue: If a locale isn’t loaded, formatting falls back to the default, which may not be desired.
    • Tip: Explicitly set a fallback locale in AddressFormatter:
      $formatter = new AddressFormatter($countryRepository, [], 'en_US');
      
  5. Performance with Large Datasets

    • Issue: Parsing/formatting many addresses in bulk can be slow due to CLDR data loading.
    • Tip: Cache the CountryRepository instance and preload frequently used countries.
  6. Custom Fields in Parsing

    • Issue: Custom fields (e.g., apartment) won’t be parsed automatically.
    • Tip: Use regex or post-processing to extract custom fields:
      if (preg_match('/#(\d+)/', $rawAddress, $matches)) {
          $address->apartment = $matches[1];
      }
      

Debugging Tips

  1. Validate CLDR Data

    // Check if a country is loaded
    if (!$countryRepository->hasCountry('US')) {
        $countryRepository->loadCountry('US', 'en_US');
    }
    
  2. Inspect Parsed Addresses

    // Dump parsed address components
    dd($address->getPostalCode(), $address->getAdministrativeArea());
    
  3. Handle Unknown Countries

    try {
        $address = $addressParser->parseStrict($rawAddress, 'XX'); // 'XX' = unknown
    } catch (UnknownCountryException $e) {
        // Fallback logic
    }
    
  4. Logging Parsing Issues

    try {
        $address = $addressParser->parseStrict($rawAddress, 'US');
    } catch (AddressParseException $e) {
        Log::warning('Address parsing failed', [
            'raw_address' => $rawAddress,
            'error' => $e->getMessage(),
        ]);
    }
    

Extension Points

  1. Custom Address Formatter Styles Extend AddressFormatter to add new formatting styles:

    class CustomFormatter extends AddressFormatter {
        public const STYLE_CUSTOM = 'custom';
    
        protected function getStyleRules($style) {
            $rules = parent::getStyleRules($style);
            if ($style === self::STYLE_CUSTOM) {
                $rules = ['line1', 'line2', 'postal_code'];
            }
            return $rules;
        }
    }
    
  2. Custom Validation Rules Create a Laravel validation rule for addresses:

    // app/Rules/ValidAddress.php
    public function passes($attribute, $value) {
        $address = $this->parser->parse($value, $this->countryCode);
        return $address->isValid();
    }
    
  3. Override CLDR Data For testing or custom locales, override CLDR data by extending the CountryRepository:

    class CustomCountryRepository extends CountryRepository {
        public function __construct() {
            parent::__construct();
            $this->overrideCountryData('US', [
                'subdivisions' => ['CA' => 'California (Custom)'],
            ]);
        }
    }
    
  4. Add Custom Address Fields Extend the Address class to support additional fields:

    class ExtendedAddress extends Address
    
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.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport