Re: [rfc] str_mask function

From: Date: Fri, 18 Sep 2026 18:53:29 +0000
Subject: Re: [rfc] str_mask function
References: 1  Groups: php.internals 
Request: Send a blank email to internals+get-132540@lists.php.net to get a copy of this message
Hi Sepehr, I have a few concerns with the current semantics before this becomes another permanent global API. The RFC motivates str_mask() primarily around sensitive data and privacy, but the proposed behavior is fail-open: str_mask('AB', '*', 3) === 'AB' An incorrect offset therefore returns the original sensitive value unchanged. If masking is being presented as the reason for introducing the function, why is an invalid masking range considered successful rather than exceptional? Silently leaking the input seems like a particularly surprising contract for an API whose stated purpose is hiding data. There is a similar issue with $mask_char. The signature accepts string, but the RFC specifies that only the first byte is used. So: str_mask($value, '●', ...) does not mask using the character that was passed. It takes one byte from a multibyte UTF-8 sequence and can produce invalid UTF-8. I understand that str_mask() is intended to be byte-oriented, but then accepting an arbitrary string and silently truncating it to one byte feels like the wrong API. Why not require exactly one byte and throw ValueError otherwise? My larger concern, though, is whether the primitive itself earns a place in core. The RFC's email example still needs strpos() and strlen() to determine where the semantic part to hide actually is. Credit cards, emails, phone numbers, tokens and identifiers all have different disclosure rules. PHP cannot determine those rules; the caller still has to do that work. Once the caller already knows the offset and length, the remaining operation is essentially replacement of a substring with a repeated byte. So I think there are three questions that need stronger answers: 1. What recurring capability does str_mask() provide that cannot already be expressed clearly with existing string primitives? 2. Do we have evidence from real-world codebases that this pattern occurs frequently enough to justify another global function rather than a small userland abstraction? 3. The RFC states that the implementation is "significantly faster". Could you include reproducible benchmarks against an equivalent substr_replace()/str_repeat() implementation, including short strings representative of the examples in the RFC? For operations on strings this small, C being faster in isolation does not necessarily establish that the difference is meaningful enough to justify expanding the standard library. I would also avoid describing this as providing privacy or GDPR compliance. Whether exposing part of an identifier is appropriate is contextual, and a generic byte-level replacement operation cannot provide that guarantee. I think these questions should be resolved before discussing the implementation itself. Best regards, Pratik Bhujel >

« previous php.internals (#132540) next »