در تاریخ یکشنبه ۲۰ سپتامبر ۲۰۲۶، ۰۴:۴۳ Pratik Bhujel < [email protected]> نوشت:
> Hi Sepehr, > > Thanks. I think we may be talking past each other slightly. > > When I see major frameworks like CakePHP having to implement custom > utility functions for simple tasks like string masking, it suggests that we > are reinventing the wheel. > > That shows that masking is a real use case, which I don’t dispute. What > I’m still missing is evidence that this *specific primitive* is what > those projects are repeatedly reinventing. > > If CakePHP is part of the motivation, I think the strongest evidence would > be to show an actual CakePHP implementation/use case that could be replaced > by: > > str_mask(string, mask_char, offset, length) > > without changing its semantics. Even better would be a small prior-art > section with several independent libraries/frameworks converging on roughly > the same operation. > > Otherwise, “frameworks implement masking” establishes the problem, but not > necessarily this particular API as the abstraction PHP core should > standardize. > > The evidence for my point is available in my RFC. > > I did read it. My concern is exactly the distinction above: evidence that > masking exists is different from evidence that this API is the common > missing primitive. > > Assuming the recent semantic issues have now been addressed, this is the > part I would focus on before implementation-level optimization. A concrete > before/after from the cited real-world code would make the case much easier > to evaluate. > > Best regards, > Pratik Bhujel > > On Sat, 19 Sep 2026 20:53:50 +0330, “سپهر محمودی” [email protected] > wrote: > > در تاریخ شنبه ۱۹ سپتامبر ۲۰۲۶، ۱۵:۲۰ Pratik Bhujel > [email protected] نوشت: > > Hi Sepehr, > > I don’t think benchmarks actually answer the main objection being raised > here. They can show that a dedicated C implementation is faster than > composing substr_replace() and str_repeat(), but they cannot show that this > operation deserves a permanent core API. > > Before optimizing it, I’d rather see evidence that the abstraction itself > is common: for example, a corpus analysis of real PHP > applications/frameworks showing how often this exact offset/length masking > pattern occurs and what existing implementations look like. Otherwise we > may just be benchmarking a convenience wrapper. > > Also, the current RFC still documents out-of-bounds offsets as returning > the original string unchanged, despite your reply saying it was changed to > fail-closed, and it still says a multi-byte $mask_char is silently reduced > to its first byte. Those semantics should probably be made consistent first. > > And Jordi’s #[SensitiveParameter] point seems especially relevant if > handling sensitive data is the primary motivation. > > So I think the order should be: demonstrate the use-case, settle the > contract, then benchmark the implementation. > > Best regards, > > Pratik Bhujel > > Hi Pratik, > > Thank you for your feedback and for taking the time to review my proposal. > > You make some very valid points regarding optimization. I completely agree > with you that performance within the PHP core is critical and must meet the > highest standards. > > My main motivation for this RFC is to address a practical need in > real-world scenarios. When I see major frameworks like CakePHP having to > implement custom utility functions for simple tasks like string masking, it > suggests that we are reinventing the wheel. Standardizing this capability > within the PHP core would be a significant benefit to the entire ecosystem. > > I would be very happy to hear your specific thoughts on the > implementation. If you have any suggestions on how I can improve the > proposal or address your concerns, I am very open to that discussion. > > The evidence for my point is available in my RFC. > > Looking forward to hearing from you. > > Best regards, > > Sepehr > > ---------- Hi Pratik, Fair point! I see what you mean now. You're completely right that just showing "masking is needed" isn't enough—I need to show why this specific `(string, mask_char, offset, length)` signature is the right primitive to standardize. To answer that directly: When people build custom masking logic today, almost everyone lands on composing `substr_replace()`, `str_repeat()`, and `strlen()`: // What people write today: $masked = substr_replace( $pan, str_repeat('*', $length ?? (strlen($pan) - $offset)), $offset, $length ?? (strlen($pan) - $offset) ); // What str_mask replaces it with: $masked = str_mask($pan, '*', $offset, $length); They end up using these exact parameters because offset and length are already the standard way PHP handles string slicing (like in `substr` and `substr_replace`). Other frameworks and internal tools (like Laravel's `Str::mask`) also converge on this exact signature because it's the most natural fit for PHP's existing conventions. The big difference with making this a core primitive isn't just saving a line of code—it's getting fail-closed error handling (throwing `ValueError` instead of silently messing up or leaking data), built-in `#[SensitiveParameter]` protection, and avoiding temporary string allocations in memory. I've updated the RFC with a quick Before/After comparison to make this clearer. Appreciate the feedback, it really helped sharpen the focus! Cheers, Sepehr
