Re: [rfc] str_mask function
| From: | سپهر محمودی | Date: | Mon, 21 Sep 2026 10:16:07 +0000 |
| Subject: | Re: [rfc] str_mask function | ||
| References: | 1 2 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-132572@lists.php.net to get a copy of this message | ||
در تاریخ دوشنبه ۲۱ سپتامبر ۲۰۲۶، ۰۴:۳۱ Ilia <ilia@ilia.ws>
نوشت:
> Why is this needed in php itself? Masking seems very use-case specific and
> would be better done inside php library with extensible modules for
> different types of data to mask.
>
> Ilia Alshanetsky
> Technologist, CTO, Entrepreneur
> E: ilia@ilia.ws
> T: @iliaa
> B: http://ilia.ws
>
> On Fri, Sep 18, 2026, 2:29 p.m. سپهر محمودی <sepehrphpr@gmail.com> wrote:
>
>> Hi everyone,
>>
>> I'm officially starting my work on the ext/intl and standard string
>> functions, and I'm very excited to share my first major proposal for PHP
>> 8.7!
>>
>> I have successfully set up my local development environment and compiler
>> on my machine, and everything is up and running smoothly.
>>
>> As part of this, I would like to propose a new native function called
>> str_mask().
>>
>> ### Proposal Overview
>> The str_mask() function is designed to securely mask portions of a string
>> using a specified mask character. This is extremely useful for handling
>> sensitive user data like credit card numbers, phone numbers, and tokens.
>>
>> Signature:
>> str_mask(string $string, string $mask_char = '*', int $offset = 0, ?int
>> $length = null): string
>>
>> ### Examples
>> 1. Masking a credit card (positive offset & length):
>> $credit_card = '1234567890123456';
>> $masked_card = str_mask($credit_card, '*', 4, 8);
>> // Output: 1234********3456
>>
>> 2. Masking a phone number (negative offset to count from the end):
>> $phone_number = '+989123456789';
>> $masked_phone = str_mask($phone_number, 'X', -4);
>> // Output: +9891234XXXX
>>
>> You can find all the details, implementation plans, and RFC discussions
>> here:
>> https://wiki.php.net/rfc/str_mask
>>
>> Looking forward to hearing your feedback and thoughts!
>>
>> Best regards,
>> Sepehr Mahmoudi
>>
> ---------
Hi Ilia,
Thanks for sharing your perspective.
I completely agree that high-level, schema-aware masking (such as
formatting credit cards, emails, or complex data structures) belongs in
userland libraries and extensible packages.
However,
str_mask() is intentionally not designed to be a high-level
formatter or business-logic helper. Instead, it is a low-level, positional
string primitive—analogous to str_pad() or substr_replace()—that
simply
replaces a byte range with a repeating character without intermediate
string allocations.
Userland libraries currently implement this through `substr_replace($str,
str_repeat(...))` or regex loops, incurring repeated string allocations and
edge-case validation overhead. Having a single native primitive provides
the fast, fail-safe foundation that those higher-level libraries can build
upon.
Best regards,
Sepehr
>>