[PHP-DEV] Array arguments for str functions

Hi all,

I would like to create an RFC proposal suggesting modifying the str_contains, str_starts_with and str_ends_with functions so that they can accept an array argument for the $needle parameter (apart from accepting a string as they do now). If an array is passed and the $haystack string contains, starts with or ends with any of the strings in the array then the functions will return true, otherwise returns false.

I looked at the RFCs where these functions were added and at the related internal discussions and could not find any discussion about this possibility.
Before creating the RFC I would like to hear the thoughts of the group, many thanks in advance

Cheers

Carlos

On 15 March 2026 08:20:38 CET, Barel <barel.barelon@gmail.com> wrote:

Hi all,

I would like to create an RFC proposal suggesting modifying the
str_contains, str_starts_with and str_ends_with functions so that they can
accept an array argument for the $needle parameter (apart from accepting a
string as they do now). If an array is passed and the $haystack string
contains, starts with or ends with any of the strings in the array then the
functions will return true, otherwise returns false.

I looked at the RFCs where these functions were added and at the related
internal discussions and could not find any discussion about this
possibility.
Before creating the RFC I would like to hear the thoughts of the group,
many thanks in advance

Cheers

Carlos

The semantics for starts_with and ends_with are easy to argue they should mean any element, but for str_contains it could be useful to have either all, or any.

I'm therefore thinking it might be better to have separate functions to make this clear.

cheers
Derick

On Sun, 15 Mar 2026 at 09:20, Derick Rethans <derick@php.net> wrote:

On 15 March 2026 08:20:38 CET, Barel <barel.barelon@gmail.com> wrote:

Hi all,

I would like to create an RFC proposal suggesting modifying the
str_contains, str_starts_with and str_ends_with functions so that they can
accept an array argument for the $needle parameter (apart from accepting a
string as they do now). If an array is passed and the $haystack string
contains, starts with or ends with any of the strings in the array then the
functions will return true, otherwise returns false.

I looked at the RFCs where these functions were added and at the related
internal discussions and could not find any discussion about this
possibility.
Before creating the RFC I would like to hear the thoughts of the group,
many thanks in advance

Cheers

Carlos

The semantics for starts_with and ends_with are easy to argue they should mean any element, but for str_contains it could be useful to have either all, or any.

I’m therefore thinking it might be better to have separate functions to make this clear.

cheers
Derick

Thanks Derick,

While “contains all” semantics can be useful in some niche scenarios, I believe they are much less frequent than the “contains any” semantics. And “contains any” is the direct parallel to the proposed behavior for str_starts_with() and str_ends_with(), keeping the mental model consistent across all three functions. Would like to hear the thoughts of other people about this issue

Cheers

Carlos

On 2026-03-15 20:20, Barel wrote:

Hi all,

I would like to create an RFC proposal suggesting modifying the | str_contains, |str_starts_with and str_ends_with functions so that they can accept an array argument for the |$needle| parameter (apart from accepting a string as they do now). If an array is passed and the | $haystack| string contains, starts with or ends with any of the strings in the array then the functions will return true, otherwise returns false.

I looked at the RFCs where these functions were added and at the related internal discussions and could not find any discussion about this possibility.
Before creating the RFC I would like to hear the thoughts of the group, many thanks in advance

Cheers

Carlos

The functions were added after it was pointed out that userland implementations tended to result in the information being derived internally and then thrown away, requiring the user to reconstruct it; it made sense to yield that internal information directly.

For this extension, I'm not sure what the advantages are over simple function composition (array_any was introduced for exactly this sort of job and is applicable to any function). Or disadvantages (e.g. more complex function signature).

Hi

Am 2026-03-16 01:41, schrieb Morgan:

For this extension, I'm not sure what the advantages are over simple function composition (array_any was introduced for exactly this sort of job and is applicable to any function)

I agree. Especially since the Partial Function Application RFC was accepted an ad-hoc implementation would just be:

     $str = 'bazinga';

     $strStartsWithAny = \array_any(['foo', 'bar', 'baz'], \str_starts_with($str, ?));

I have also added an optimization to PHP 8.6 that compiles `array_map()` into a foreach loop when the callback is first class callable or PFA: zend_compile: Optimize `array_map()` with callable convert callback into foreach by TimWolla · Pull Request #20934 · php/php-src · GitHub. I plan to extend this to the other array_* functions once the PFA PR is merged.

Best regards
Tim Düsterhus

On Mon, 16 Mar 2026 at 15:32, Tim Düsterhus <tim@bastelstu.be> wrote:

Hi

Am 2026-03-16 01:41, schrieb Morgan:

For this extension, I’m not sure what the advantages are over simple
function composition (array_any was introduced for exactly this sort of
job and is applicable to any function)

I agree. Especially since the Partial Function Application RFC was
accepted an ad-hoc implementation would just be:

$str = ‘bazinga’;

$strStartsWithAny = \array_any([‘foo’, ‘bar’, ‘baz’],
\str_starts_with($str, ?));

I have also added an optimization to PHP 8.6 that compiles array_map()
into a foreach loop when the callback is first class callable or PFA:
https://github.com/php/php-src/pull/20934. I plan to extend this to the
other array_* functions once the PFA PR is merged.

Best regards
Tim Düsterhus

Tim, Morgan

Thanks for your comments. I did not realise that this would be easily implemented by using array_any. This means that the RFC that I was planning to create is not actually needed

Cheers

Carlos

On Mon, Mar 16, 2026, at 9:30 AM, Tim Düsterhus wrote:

I have also added an optimization to PHP 8.6 that compiles `array_map()`
into a foreach loop when the callback is first class callable or PFA:
zend_compile: Optimize `array_map()` with callable convert callback into foreach by TimWolla · Pull Request #20934 · php/php-src · GitHub. I plan to extend this to the
other array_* functions once the PFA PR is merged.

Best regards
Tim Düsterhus

!!! I didn't realize you'd done so. That's awesome, and needs more publicity. :slight_smile:

With all the compile optimizations around pipes, PFA, etc., I wonder if there's a way to make it more generic? Like, can tools be built for pipes and PFA that can get down-compiled, without having to special case everything in the engine?

--Larry Garfield