Table of Contents

RFC: array_str_contains

Introduction

Finding elements in an array that contain a specific substring is a very common task in PHP. Currently, developers must rely on array_filter() combined with a userland closure and str_contains(), or write a custom foreach loop.

Executing a userland callback for every element in a large array using array_filter() introduces unnecessary performance overhead. This RFC proposes a native C function, array_str_contains(), to perform this task efficiently, eliminating the closure overhead and providing a much cleaner, more readable syntax.

Proposal

This RFC proposes the addition of a new array function:

function array_str_contains(
    array $array,
    string $needle
): array {}

Parameters:

The function searches for the exact substring $needle in the values of the $array. It returns a new array containing only the matched elements.

Use Cases

This function simplifies many common filtering tasks, including but not limited to:

Examples

$files = [
    'image.jpeg',
    'script.php',
    'index.PHP',
    'document.pdf',
    'functions.php'
];
 
$result = array_str_contains(
    $files,
    '.php'
);
 
print_r($result);
 
/* Output:
Array
(
    [1] => script.php
    [4] => functions.php
)
*/

Explanation: The function searches for the exact substring .php in the array values. It is case-sensitive, so index.PHP is not matched. Original array keys are preserved.

Example 2: Searching in Log Lines

$logs = [
    200 => 'INFO: Application started',
    201 => 'ERROR: Database timeout',
    202 => 'WARNING: CPU load high',
    203 => 'ERROR: Invalid user input'
];
 
$errors = array_str_contains($logs, 'ERROR:');
 
print_r($errors);
 
/* Output:
Array
(
    [201] => ERROR: Database timeout
    [203] => ERROR: Invalid user input
)
*/

Explanation: This example demonstrates filtering a list of log messages to easily extract the lines containing the “ERROR:” substring. Custom keys are maintained in the result.

Example 3: Handling Non-String Values

$data = [
    'user_100',
    100,
    10055,
    'guest',
    true
];
 
$matches = array_str_contains($data, '100');
 
print_r($matches);
 
/* Output:
Array
(
    [0] => user_100
    [1] => 100
    [2] => 10055
)
*/

Explanation: Non-string values are implicitly cast to strings before the comparison. For instance, the integer 100 becomes the string “100”, which successfully matches the needle “100”.

Polyfill / Userland Equivalent

The behavior of the proposed function can be illustrated by the following userland implementation. (Note: This approach uses a standard loop to avoid the closure overhead typical of array_filter()):

function array_str_contains(array $array, string $needle): array {
    $result = [];
    foreach ($array as $key => $value) {
        // Cast to string to handle non-string values safely, matching str_contains behavior
        if (str_contains((string) $value, $needle)) {
            $result[$key] = $value;
        }
    }
    return $result;
}

Backward Incompatible Changes

None.

Proposed PHP Version(s)

Next minor version (PHP 8.7).

RFC Impact

Open Issues

None at this time.

Proposed Voting Choices

State whether to accept the RFC and merge the patch into PHP 8.7. As this is a standard feature addition, it requires a 2/3 majority to pass.

Implementation

In Progress (TBD).