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

Polyfill Intl Idn Laravel Package

symfony/polyfill-intl-idn

Provides polyfills for the Intl IDN functions idn_to_ascii() and idn_to_utf8(), enabling Internationalized Domain Name conversion on PHP installations without the intl extension. Part of Symfony’s Polyfill suite, MIT licensed.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation: Add the package via Composer:

    composer require symfony/polyfill-intl-idn
    

    No additional configuration is required.

  2. First Use Case: Convert an internationalized domain name (IDN) to ASCII (Punycode) for storage or DNS resolution:

    use Symfony\Component\Polyfill\Intl\Idn\IdnPolyfill;
    
    $asciiDomain = IdnPolyfill::toAscii('例子.测试'); // Returns 'xn--fsq.xn--0zwm56d'
    

    Or convert ASCII back to UTF-8 for display:

    $utf8Domain = IdnPolyfill::toUtf8('xn--fsq.xn--0zwm56d'); // Returns '例子.测试'
    
  3. Where to Look First:

    • Documentation: Symfony Polyfill README
    • Source Code: Focus on IdnPolyfill.php for implementation details.
    • Tests: Review existing tests in the package for edge cases (e.g., invalid input, mixed scripts).

Implementation Patterns

Usage Patterns

  1. Domain Normalization: Use toAscii() for storing domains in databases or APIs where ASCII is required:

    $userInput = '北京.测试';
    $normalized = IdnPolyfill::toAscii($userInput);
    // Store $normalized in DB or use in DNS queries
    
  2. Email Validation: Validate internationalized email addresses by extracting and converting the domain:

    $email = '用户@例子.测试';
    $domain = explode('@', $email)[1];
    $asciiDomain = IdnPolyfill::toAscii($domain);
    // Proceed with validation logic
    
  3. URL Generation: Convert IDNs to ASCII for URLs to ensure compatibility with legacy systems:

    $url = 'https://例子.测试';
    $asciiUrl = str_replace('例子.测试', IdnPolyfill::toAscii('例子.测试'), $url);
    // Use $asciiUrl in redirects or API calls
    
  4. Laravel Integration: Create a helper function in app/Helpers/IdnHelper.php:

    use Symfony\Component\Polyfill\Intl\Idn\IdnPolyfill;
    
    if (!function_exists('idn_to_ascii')) {
        function idn_to_ascii($domain) {
            return IdnPolyfill::toAscii($domain);
        }
    }
    
    if (!function_exists('idn_to_utf8')) {
        function idn_to_utf8($domain) {
            return IdnPolyfill::toUtf8($domain);
        }
    }
    

    Register the helper in composer.json autoload:

    "autoload": {
        "files": ["app/Helpers/IdnHelper.php"]
    }
    
  5. Caching: Cache frequent conversions to mitigate performance overhead:

    $cacheKey = 'idn_ascii_' . md5($domain);
    $asciiDomain = cache()->remember($cacheKey, now()->addHours(1), function () use ($domain) {
        return IdnPolyfill::toAscii($domain);
    });
    

Workflows

  1. User Input Handling:

    • Sanitize and convert IDNs early in the request lifecycle (e.g., middleware or form requests).
    • Example middleware:
      public function handle($request, Closure $next) {
          if ($request->has('domain')) {
              $request->merge([
                  'domain_ascii' => IdnPolyfill::toAscii($request->input('domain'))
              ]);
          }
          return $next($request);
      }
      
  2. API Responses:

    • Convert ASCII domains back to UTF-8 for API responses to improve readability:
      return response()->json([
          'domain' => IdnPolyfill::toUtf8($storedAsciiDomain)
      ]);
      
  3. Testing:

    • Mock the polyfill in tests to avoid dependency on external functions:
      use Symfony\Component\Polyfill\Intl\Idn\IdnPolyfill;
      
      beforeEach(function () {
          $this->mock(IdnPolyfill::class)->shouldReceive('toAscii')
              ->andReturn('xn--fsq.xn--0zwm56d');
      });
      

Integration Tips

  1. Laravel Validation: Extend Laravel’s validation rules to support IDNs:

    use Illuminate\Validation\Rule;
    
    Rule::macro('valid_idn_domain', function ($format = null) {
        return function ($attribute, $value, $parameters) {
            $ascii = IdnPolyfill::toAscii($value);
            return preg_match('/^([a-z\d-]+\.)+[a-z\d-]{2,}$/i', $ascii);
        };
    });
    

    Usage:

    'domain' => ['required', 'valid_idn_domain'],
    
  2. Database Storage: Store domains in ASCII format in the database and convert back to UTF-8 when retrieving:

    // Store
    $user->domain = IdnPolyfill::toAscii($request->domain);
    $user->save();
    
    // Retrieve
    $domain = IdnPolyfill::toUtf8($user->domain);
    
  3. DNS and API Calls: Use ASCII domains for DNS lookups or API calls to ensure compatibility:

    $asciiDomain = IdnPolyfill::toAscii($userInputDomain);
    $dnsResult = dns_get_record($asciiDomain);
    
  4. Localization: Combine with Laravel’s localization features for multilingual support:

    $locale = app()->getLocale();
    $translatedDomain = __("domains.$locale.example");
    $asciiDomain = IdnPolyfill::toAscii($translatedDomain);
    

Gotchas and Tips

Pitfalls

  1. Invalid Input Handling: The polyfill may return false for invalid input (e.g., malformed Unicode). Always validate:

    $asciiDomain = IdnPolyfill::toAscii($domain);
    if ($asciiDomain === false) {
        throw new \InvalidArgumentException("Invalid IDN: $domain");
    }
    
  2. Performance Overhead: Polyfills are slower than native Intl functions. Benchmark critical paths and cache results:

    // Benchmark example
    $start = microtime(true);
    IdnPolyfill::toAscii('例子.测试');
    $time = microtime(true) - $start;
    // Log or alert if $time > 0.01 (10ms threshold)
    
  3. Behavioral Differences: The polyfill may handle edge cases differently than the native Intl extension. Test with:

    • Mixed scripts (e.g., 例子.测试.例子).
    • Rare Unicode characters (e.g., emoji, private-use areas).
    • Invalid sequences (e.g., 例子..测试).
  4. Caching Issues: Avoid caching toUtf8() results for user-generated content, as they may change over time (e.g., domain updates).

  5. PHP Version Quirks:

    • In PHP < 7.4, the polyfill may not handle all Unicode edge cases due to older PHP internals.
    • Test on the target PHP version to catch regressions.

Debugging

  1. Unexpected Output: If toAscii() or toUtf8() returns unexpected results, verify the input:

    $domain = '例子.测试';
    echo "Input: " . bin2hex($domain) . "\n"; // Debug raw bytes
    echo "Output: " . IdnPolyfill::toAscii($domain) . "\n";
    
  2. False Returns: Check for false returns and handle gracefully:

    $result = IdnPolyfill::toAscii($domain);
    if ($result === false) {
        // Log the input for debugging
        \Log::error("IDN conversion failed for: $domain", ['input' => bin2hex($domain)]);
    }
    
  3. Memory Leaks: The polyfill is stateless, but complex conversions may consume memory. Monitor with:

    composer require --dev ext-meminfo
    

    Then in code:

    $memoryBefore = memory_get_usage();
    $result = IdnPolyfill::toAscii($domain);
    $memoryAfter = memory_get_usage();
    if ($memoryAfter - $memoryBefore > 1024 * 1024) { // >1MB
        \Log::warning("High memory usage in IDN conversion");
    }
    

Tips

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.
codraw/entity-migrator
codraw/doctrine-extra
codraw/aws-tool-kit
codraw/validator
codraw/workflow
codraw/open-api
codraw/cron-job
codraw/process
codraw/log
nexmo/api-specification
capell-app/block-library
axium/identity
cetria/laravel-dummy-models
cetria/reflection-helper
agropredict/sso-auth-bundle
evolvestudio/spam-protection
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony