symfony/polyfill-iconv
Native PHP polyfill for the iconv extension, providing drop-in implementations of iconv functions (except ob_iconv_handler). Useful when iconv isn’t available, helping ensure consistent behavior across environments.
Installation:
composer require symfony/polyfill-iconv
require (not require-dev) if needed in production.ext-iconv is missing.First Use Case: Test basic encoding conversion in a Laravel controller or command:
use Illuminate\Support\Facades\Log;
// Example: Convert user input to ASCII (ignore unsupported chars)
$userInput = "Café";
$asciiOutput = iconv('UTF-8', 'ASCII//IGNORE', $userInput);
Log::info("Converted: {$asciiOutput}"); // Logs "Converted: Cafe"
Verify Polyfill Activation:
Simulate a missing ext-iconv environment:
php -d extension=-iconv artisan tinker
Run the same iconv() call in Tinker to confirm it works without native extension.
Drop-in Replacement:
Replace all iconv() calls with the polyfill’s native functions. No wrappers or adapters are needed:
// Before/After: No code changes required
$converted = iconv('UTF-8', 'ASCII//TRANSLIT', $string);
Environment-Specific Logic:
Use the polyfill to handle edge cases where native iconv might fail:
// Safely convert with fallback
$result = @iconv('UTF-8', 'ASCII//IGNORE', $text) ?: $text;
File Handling: Sanitize filenames or content from non-Latin scripts:
// Laravel File Upload Example
$filename = $request->file('resume')->getClientOriginalName();
$sanitized = iconv('UTF-8', 'ASCII//IGNORE', $filename);
$request->file('resume')->move(storage_path('uploads'), $sanitized);
Database Integration:
Normalize legacy encodings (e.g., ISO-8859-1) to UTF-8 for storage:
// Laravel Eloquent Example
$record->title = iconv('ISO-8859-1', 'UTF-8', $rawTitle);
$record->save();
Testing: Force polyfill usage in tests to catch encoding issues early:
// In phpunit.xml or test case setup
putenv('PHP_EXT_ICONV=0'); // Simulate missing extension
Multilingual Content Workflow:
Str::of() for additional string manipulation:
$cleanText = Str::of(iconv('UTF-8', 'ASCII//TRANSLIT', $userComment))->lower();
Legacy System Migration:
mbstring calls with iconv where consistency is critical.mb_strlen() with iconv_strlen() for byte-length calculations.CI/CD Pipeline:
ext-iconv:
# GitHub Actions Example
jobs:
test:
runs-on: ubuntu-latest
steps:
- run: php -d extension=-iconv vendor/bin/phpunit
Laravel-Specific:
HandleUploadedFile or custom request handlers.FormRequest to sanitize input:
protected function sanitizeInput($input) {
return iconv('UTF-8', 'ASCII//IGNORE', $input);
}
Performance Optimization:
$cacheKey = 'translation_' . md5($locale . $key);
$translation = Cache::remember($cacheKey, now()->addHours(1), function() use ($locale, $key) {
return iconv('UTF-8', 'ASCII//TRANSLIT', $rawTranslation);
});
Monitoring:
if (!extension_loaded('iconv')) {
Log::warning('Using symfony/polyfill-iconv; consider enabling ext-iconv in production.');
}
Unsupported Features:
ob_iconv_handler: Not polyfilled. Use mbstring output buffering instead:
ob_start('mb_output_handler');
iconv_get_encoding(): Fall back to mb_internal_encoding():
$encoding = mb_internal_encoding();
Performance Overhead:
iconv. Profile with Blackfire or Xdebug to identify bottlenecks.// Bad: Polyfill in tight loop
foreach ($largeDataset as $item) {
$converted = iconv('UTF-8', 'ASCII//IGNORE', $item->text);
}
Edge Cases:
//TRANSLIT) may produce unexpected results. Test thoroughly.if (!mb_check_encoding($text, 'UTF-8')) {
$text = mb_convert_encoding($text, 'UTF-8', 'auto');
}
False Positives:
ext-iconv is missing. Ensure testing accounts for this:
# Test with polyfill
php -d extension=-iconv artisan test
# Test with native extension (if available)
php artisan test
Verify Polyfill Activation:
if (!extension_loaded('iconv')) {
echo "Using polyfill: " . class_exists('Symfony\Polyfill\Iconv\Iconv') ? 'Yes' : 'No';
}
Common Errors:
iconv() Warnings: Check for invalid character sets or malformed input.$fixed = iconv('UTF-8', 'UTF-8//IGNORE', $garbledText);
Logging:
Log::debug("iconv('{$from}', '{$to}', '{$text}') => " . iconv($from, $to, $text));
Configuration:
config/ or service provider setup is needed. The polyfill auto-registers via Composer.Testing:
RefreshDatabase trait with polyfill-enabled tests:
use Illuminate\Foundation\Testing\RefreshDatabase;
class EncodingTest extends TestCase {
use RefreshDatabase;
public function testPolyfillWorks() {
$this->assertEquals('Cafe', iconv('UTF-8', 'ASCII//IGNORE', 'Café'));
}
}
Extension Points:
Symfony\Polyfill\Iconv\Iconv for proprietary encoding schemes (rarely needed).if (config('app.use_iconv_polyfill')) {
// Force polyfill (for testing)
if (extension_loaded('iconv')) {
dl('iconv.so'); // Unload native extension (Linux)
}
}
Alternatives:
mbstring-only projects, consider symfony/polyfill-mbstring instead.ext-iconv in production and use the polyfill only in CI/staging.Laravel-Specific:
Illuminate\Filesystem\Filesystem to use polyfill for path sanitization.Illuminate\Validation\Validator to handle encoded input:
$validator->extend('encoded', function ($attribute, $value, $parameters) {
return iconv('UTF-8', 'ASCII//IGNORE', $value) === $value;
});
How can I help you explore Laravel packages today?