strrchr with needle with multiple characters

php.internals

Vincent Langlet

1 year ago
I was today old when I discovered the big difference between strchr and strrchr in the way they handle needle with multiple characters. It's explained in the doc https://www.php.net/manual/en/function.strrchr.php - If needle contains more than one character, only the first is used. This behavior is different from that of strstr() <https://www.php.net/manual/en/function.strstr.php>. You can see an example https://3v4l.org/7j5ab I feel like this behavior has no benefit (if I want to look for the first character, I can pass `substr($needle, 0, 1)` instead) and is just error-prone. Is there a reason for such behavior ? Would it be easy to change it (I have no knowledge at all in C and in the existing PHP code) ?

David CARLIER

1 year ago
Hi, On Mon, 2 Sept 2024 at 12:20, Vincent Langlet <misterdeviling@gmail.com> wrote:
> I was today old when I discovered the big difference between strchr and > strrchr in the way they handle needle with multiple characters. > > It's explained in the doc > https://www.php.net/manual/en/function.strrchr.php > - If needle contains more than one character, only the first is used. > This behavior is different from that of strstr() > <https://www.php.net/manual/en/function.strstr.php>. > > You can see an example https://3v4l.org/7j5ab > > I feel like this behavior has no benefit (if I want to look for the first > character, I can pass `substr($needle, 0, 1)` instead) and is just > error-prone. > > Is there a reason for such behavior ? Would it be easy to change it (I > have no knowledge at all in C and in the existing PHP code) ? >
It is a bit ambiguous, I'll give you that, albeit you can pass a string to str(r)chr only the first character is used, these are literally similar to their C counterparts https://www.tutorialspoint.com/c_standard_library/c_function_strchr.htm https://www.tutorialspoint.com/c_standard_library/c_function_strrchr.htm see the second argument handles one character at a time. Cheers.

Christoph Becker

1 year ago
On 02.09.2024 at 13:17, Vincent Langlet wrote:
> I was today old when I discovered the big difference between strchr and > strrchr in the way they handle needle with multiple characters. > > It's explained in the doc https://www.php.net/manual/en/function.strrchr.php > - If needle contains more than one character, only the first is used. This > behavior is different from that of strstr() > <https://www.php.net/manual/en/function.strstr.php>. > > You can see an example https://3v4l.org/7j5ab > > I feel like this behavior has no benefit (if I want to look for the first > character, I can pass `substr($needle, 0, 1)` instead) and is just > error-prone. > > Is there a reason for such behavior ? Would it be easy to change it (I have > no knowledge at all in C and in the existing PHP code) ?
strchr() is an alias of strstr(), and I would always use the latter name, because strchr() is indeed confusing. Anyhow, strstr() is very useful in C, but not so much in PHP, since in PHP it will always allocate a new string, even if that is not needed. Now, comparing strstr() and strrchr() is of course still possible, but different behavior is less astonishing. Of course, strrchr() could warn or even throw if $needle has more than one character, but that may unnecessarily break code for a small benefit. Christoph

Tim Düsterhus

1 year ago
Hi Am 2024-09-02 15:24, schrieb Christoph M. Becker:
> Now, comparing strstr() and strrchr() is of course still possible, but > different behavior is less astonishing. Of course, strrchr() could > warn > or even throw if $needle has more than one character, but that may > unnecessarily break code for a small benefit.
I would expect that passing more than one character to `strrchr()` is very likely to be an accident or a misunderstanding of how the function behaves and thus already broken. A warning would just visibly point out that it is broken, instead of it silently behaving in a manner that diverges from the user's expectations (possibly unpredictably if the function is working on untrusted / user input). If the function would be newly introduced, I'd make it an error to pass more than one character, but given that the function already exists, I'd say that pointing out such mistakes is exactly what the Warning / Notice facility is for. Best regards Tim Düsterhus