- What does symfony/polyfill-intl-grapheme actually do?
- It provides a partial, native PHP implementation of the grapheme_* functions normally supplied by PHP's intl extension. Covered functions include grapheme_strlen, grapheme_substr, grapheme_strpos, grapheme_stripos, grapheme_strrpos, grapheme_strripos, grapheme_strstr, grapheme_stristr, grapheme_extract, and grapheme_str_split. The polyfill only defines these functions when ext-intl is missing or does not already provide them, so it is a safe drop-in. Operations are grapheme-cluster aware and expect UTF-8 encoded input.
- How do I install symfony/polyfill-intl-grapheme in a Laravel app?
- Run composer require symfony/polyfill-intl-grapheme and Composer will register the polyfill's bootstrap file automatically via its autoload files entry. In many projects it already arrives transitively through symfony/string or other Symfony components, but requiring it explicitly guarantees the functions exist. No service provider, config publishing, or facade registration is needed. You can then call grapheme_strlen(), grapheme_substr(), and the rest directly in your code.
- Do I still need the intl extension if I install this polyfill?
- For the grapheme_* functions covered by this package, no. When ext-intl is loaded, its native implementations win and the polyfill stays inert; when it is absent, the polyfill takes over. The polyfill is explicitly partial, so other intl features such as collation, number and date formatting, transliteration, and message formatting still require ext-intl or separate polyfills. For Unicode normalization you would add symfony/polyfill-intl-normalizer.
- Which PHP and Laravel versions does this polyfill support?
- It is a framework-agnostic Symfony component with no Laravel dependency, so it works with any Laravel release running a PHP version the installed polyfill branch supports. Current releases target modern PHP 7.x and 8.x runtimes, and Composer picks the appropriate branch for your platform. Because it is pure PHP, it also works on shared hosting images where ext-intl has been disabled. Check the package's composer.json constraint on packagist to confirm support for a specific PHP version.
- How is grapheme_strlen different from Laravel's Str::length or mb_strlen?
- mb_strlen counts code points, and plain strlen counts bytes, but both can overcount what a user perceives as one character. A combining sequence like a letter plus a diacritic, or a ZWJ emoji sequence such as a family emoji, is a single grapheme cluster but several code points. grapheme_strlen returns the grapheme count, which is what you want for character limits, validation rules, counters, and truncation in multilingual UI. Slicing with grapheme_substr also avoids splitting a cluster mid-sequence.
- Does the polyfill handle emoji and combining characters correctly?
- Yes for the common cases: grapheme-aware length, substring, splitting, extraction, and position searches treat ZWJ emoji sequences and combining marks as single clusters. Because segmentation relies on data bundled with the polyfill rather than the system ICU library, brand-new emoji or Unicode releases may segment differently from a native ext-intl build until you update the package. If you need canonical or compatibility normalization on top of that, pair it with symfony/polyfill-intl-normalizer. Always store and pass UTF-8 strings, since the functions assume that encoding.
- What is the performance cost of using this polyfill in production?
- It is native PHP rather than a C extension, so grapheme operations are measurably slower than ext-intl, and the gap grows with string length and how many clusters must be scanned. For typical request-level work such as validating a username or truncating a title, the cost is negligible. For hot paths like bulk imports, real-time search analyzers, or per-row processing, benchmark first and consider enabling ext-intl on production hosts or caching results. A common pattern is to require the polyfill for portability while letting ext-intl serve production traffic.
- Does symfony/polyfill-intl-grapheme provide grapheme_strrev or string reversal?
- No, the package mirrors the existing intl grapheme_* API and does not add a grapheme_strrev() function. To reverse text safely you can split with grapheme_str_split(), run array_reverse(), and implode the result, which keeps RTL words and emoji clusters intact instead of breaking bytes. Wrapping that logic in a Str::macro keeps it reusable across your application. Avoid plain strrev() on any non-ASCII input, because it reverses bytes and corrupts multibyte characters.
- How do I test code that depends on this polyfill?
- Behavior is designed to match ext-intl, so ordinary PHPUnit tests asserting grapheme lengths and substrings work in either environment. To exercise the polyfill path specifically, run your suite in a container or CI job where the intl extension is not loaded, otherwise the native functions take precedence and the polyfill is bypassed. Include fixtures with Arabic, Hebrew, Persian, emoji, and combining-accent text to catch regressions. Laravel's testing helpers and Pest both work fine since the package has no framework coupling.
- Is the package well maintained, and what are the alternatives?
- It is maintained by the Symfony core team under the MIT license and is one of the most widely installed Composer packages, since it ships transitively with symfony/string and much of the ecosystem. Alternatives include simply enabling ext-intl on your servers, using symfony/string for a broader Unicode toolbox, or older packages like patchwork/utf8. Keep it as a compatibility fallback while relying on ext-intl where available, and update it regularly to pick up new Unicode segmentation data.