voku/portable-ascii
PHP 7+ library to transliterate Unicode to portable ASCII for slugs, URLs, and safe filenames. Works without mbstring/iconv, lightweight and easy to bundle. Based on Unidecode/Stringy-style mappings with handy helper methods.
Install via Composer: composer require voku/portable-ascii. Start with the high-level utility methods — ASCII::to_ascii(), ASCII::to_slugify(), and ASCII::is_ascii() — which cover 90% of day-to-day use cases like cleaning user input, generating URL slugs, or normalizing filenames. For instance, converting multilingual strings to ASCII for database keys or API payloads:
use voku\helper\ASCII;
// Basic slug generation
echo ASCII::to_slugify('Café & Bar – München'); // 'cafe-bar-munchen'
// Language-aware conversion (German vs English)
echo ASCII::to_ascii('Müller', 'de'); // 'Mueller'
echo ASCII::to_ascii('Müller', 'en'); // 'Muller'
The is_ascii() method is especially useful for performance-sensitive checks before heavier processing.
Slugification Pipeline: Use to_slugify() with language hints and custom separators for SEO-friendly URLs — ideal in Laravel route model binding or admin panel slug generation.
Input Sanitization Chain: Wrap form data with clean() and remove_invisible_characters() before storage to prevent corruption or XSS:
$clean = ASCII::clean($input, true, false, true, true);
to_filename(), with fallback characters for edge cases (e.g., emoji uploads):$safeName = ASCII::to_filename(' photo_#2024-05-01_12:30.jpg', true, '_');
Database Indexing: Pre-normalize strings for case-insensitive comparisons or full-text search indexing using to_ascii() + to_slugify().
Fallback Processing: Combine to_transliterate() with to_ascii() for robustness — transliterate unsupported chars first, then fall back to ASCII:
Language Sensitivity: Always specify the correct language (e.g., 'de_at', 'pt_BR') when to_ascii()/to_slugify() is used — default en may produce unintuitive results for non-English users (e.g., German ß → ss only in German mode). Use ASCII::getAllLanguages() to discover supported locales.
Empty/Null Handling: Methods like to_slugify() return empty strings for non-alphanumeric input. Always validate or provide a fallback.
Performance: While optimized, repeated calls on large batches benefit from caching charsArray() or precomputing maps:
$map = ASCII::charsArrayWithOneLanguage('fr');
// Then use strtr() manually for repeated transformations
Unicode Normalization ≠ ASCII Conversion: normalize_whitespace() and normalize_msword() only handle whitespace/smart punctuation — they don’t strip non-ASCII characters. Use clean() or to_ascii() after these for full sanitization.
Invisible Characters: When processing raw POST/PUT bodies (e.g., JSON from external APIs), enable remove_invisible_characters() — especially with url_encoded=true to prevent injection attacks.
Extensibility: Extend via custom replacements by merging charsArrayWithOneLanguage() with your own mapping — useful for domain-specific terms (e.g., converting – to - everywhere or & to and for SEO).
How can I help you explore Laravel packages today?