[Discussion] Proposal: grapheme_mask() helper function

php.internals

سپهر محمودی

74 days ago
Hello everyone Over the past few weeks I have been exploring a common pattern that frequently appears in PHP applications: masking sensitive parts of strings such as credit card numbers, email addresses, phone numbers, and personal identifiers. In many real-world codebases, developers typically implement masking using combinations of functions like substr(), strlen(), str_repeat(), substr_replace(), or their multibyte equivalents. While these approaches work, they often lead to repetitive, error‑prone, and sometimes inefficient user‑land implementations. Handling edge cases—especially when offsets are negative, lengths are omitted, or when working with Unicode text—can make these snippets unnecessarily complex. While thinking about this problem, I designed a function concept called grapheme_mask(). The goal of this function is to provide a clear, native, and Unicode‑safe way to mask sections of a string. The key idea is that the function operates on grapheme clusters, rather than raw bytes or individual code points. This allows it to correctly handle modern Unicode text, including composed characters and emoji sequences, without breaking them apart. Conceptually, the function replaces a range of grapheme clusters with a masking string. Example: grapheme_mask("sepehr@example.com", "*", 2, -12); // result: se****@example.com -------------------------------------------- Example with emoji sequences: grapheme_mask("👨🏽‍👩‍👧‍👦 family", "*", 0, 1); // result: * family ----------------------------------------- The intention is not to replace existing string functions, but to provide a dedicated and expressive helper for a task that developers routinely implement themselves. If there is interest from the community, I would be happy to draft a formal RFC describing the proposed behavior, edge cases, and potential implementation details. I would greatly appreciate any feedback, thoughts, or suggestions. Best regards, Sepehr

youkidearitai

74 days ago
‪2026年6月19日(金) 19:54 ‫سپهر محمودی‬‎ <sepehrphpr@gmail.com>:‬
> > Hello everyone > Over the past few weeks I have been exploring a common pattern that > frequently appears in PHP applications: masking sensitive parts of > strings such as credit card numbers, email addresses, phone numbers, > and personal identifiers. > > In many real-world codebases, developers typically implement masking > using combinations of functions like substr(), strlen(), str_repeat(), > substr_replace(), or their multibyte equivalents. While these > approaches work, they often lead to repetitive, error‑prone, and > sometimes inefficient user‑land implementations. Handling edge > cases—especially when offsets are negative, lengths are omitted, or > when working with Unicode text—can make these snippets unnecessarily > complex. > > While thinking about this problem, I designed a function concept > called grapheme_mask(). The goal of this function is to provide a > clear, native, and Unicode‑safe way to mask sections of a string. > > The key idea is that the function operates on grapheme clusters, > rather than raw bytes or individual code points. This allows it to > correctly handle modern Unicode text, including composed characters > and emoji sequences, without breaking them apart. > > Conceptually, the function replaces a range of grapheme clusters with > a masking string. > > Example: > > grapheme_mask("sepehr@example.com", "*", 2, -12); > // result: se****@example.com > -------------------------------------------- > Example with emoji sequences: > grapheme_mask("👨🏽‍👩‍👧‍👦 family", "*", 0, 1); > // result: * family > ----------------------------------------- > > The intention is not to replace existing string functions, but to > provide a dedicated and expressive helper for a task that developers > routinely implement themselves. > > If there is interest from the community, I would be happy to draft a > formal RFC describing the proposed behavior, edge cases, and potential > implementation details. > > I would greatly appreciate any feedback, thoughts, or suggestions. > > Best regards, > > Sepehr
Hi, Sepehr and Internals Thank you for bringing up discussion. Looks good to me. One more point for add that function. The diacritical mark sometimes includes one code point and separated code points. For example, Umlaut(ä, a + ¨), Dakuten(が, か + ゛) and etc in the world. These characters needs support for grapheme_mask function. Therefore, I would like need that function. Regards Yuya
-- --------------------------- Yuya Hamada (tekimen) - https://tekitoh-memdhoi.info - https://github.com/youkidearitai -----------------------------

سپهر محمودی

74 days ago
Hi everyone, I'm Sepehr, the author of this proposal. I'm glad to see the interest in grapheme_mask(). I have already developed a working prototype in C (based on ICU ubrk) along with several PHPT test cases covering Unicode and emoji clusters. I believe this addition will significantly improve how developers handle sensitive data masking in modern PHP applications. I have requested a Wiki account to start the formal RFC process and share the implementation details. Looking forward to your feedback. Best regards, Sepehr در تاریخ جمعه ۱۹ ژوئن ۲۰۲۶، ۱۸:۱۷ youkidearitai <youkidearitai@gmail.com> نوشت:

Nick

68 days ago
On 19.06.26 17:51, سپهر محمودی wrote:
> While thinking about this problem, I designed a function concept > called grapheme_mask(). The goal of this function is to provide a > clear, native, and Unicode‑safe way to mask sections of a string. > > Best regards, > > Sepehr
Hey Sepehr, Is this `grapheme_mask` proposal meant as a replacement for the `str_mask` you proposed before or as an addition? A mask function seems helpful to me. But I think this should not be exclusive to the intl extension,  and `str_mask` still be added, too.
-- Cheers Nick

سپهر محمودی

68 days ago
Hi Nick, Ilija, and everyone, Thank you for the quick feedback, Nick! I completely agree with your suggestion. Having both str_mask() for general byte-based masking and grapheme_mask() for Unicode-aware operations is the perfect approach to cover all use cases in PHP. I have already prepared the implementation, stubs, and tests for grapheme_mask. Regarding your suggestion, I’m more than happy to work on str_mask as well and include both in the proposal. However, I'm currently facing a technical issue with the PHP Wiki. My account (sepehrphp) seems to be inactive or pending activation, which is preventing me from logging in and publishing the RFC. @Ilija, could you please check my account status? As soon as the login issue is resolved, I will post the RFC covering both functions so we can discuss the implementation details there. Best regards, Sepeh On Thu, Jun 25, 2026 at 9:29 AM Nick Sdot <php@nicksdot.dev> wrote: