PHP RFC: str_icontains
- Version: 0.3
- Date: 2025-07-01
- Author: Adam Cable, adamcable@gmail.com
- Status: Voting
- First Published at: https://wiki.php.net/rfc/str_icontains
Introduction
PHP 8.0 introduced the str_contains function, which provides a clear and concise way to determine if a string contains a given substring. This was a significant improvement over the traditional method of using strpos and checking the return value.
However, a common use case is to check for the presence of a substring in a case-insensitive manner. Currently, this requires using functions like stripos or converting both the haystack and needle to the same case using strtolower or strtoupper before comparison. These approaches can be less intuitive and more error-prone.
To address this, this RFC proposes the addition of a new function, str_icontains, as a case-insensitive counterpart to str_contains. The naming convention follows the precedent set by existing string functions, such as str_replace and its case-insensitive variant, str_ireplace.
Proposal
It is proposed to add a new function to PHP:
function str_icontains(string $haystack, string $needle): bool
This function will return true if $needle is found in $haystack, with the comparison performed in a case-insensitive manner. The case-insensitivity will be based on ASCII case folding, which means it will correctly handle standard English alphabet characters (a-z, A-Z). This is consistent with the behaviour of other case-insensitive string functions in PHP, such as str_ireplace and stripos.
Use Cases
Example 1: Basic Usage
$string = "The quick brown fox jumps over the lazy dog."; str_icontains($string, 'fox'); // true str_icontains($string, 'FOX'); // true str_icontains($string, 'Fox'); // true
Example 2: Comparison with current methods
Without str_icontains, a developer would have to write:
// Using stripos stripos($string, 'FOX') !== false; // true // Using strtolower str_contains(strtolower($string), strtolower('FOX')); // true
The proposed str_icontains function is more readable and less susceptible to errors.
Why wasn't this included with str_contains?
I have reviewed the previous discussions and RFCs surrounding the initial introduction of str_contains. The reason a case-insensitive version was not included at that time was twofold:
- Limited Functional Gain: Some community members felt that the case-insensitive variant did not provide a significant enough improvement over existing userland code (e.g., strtolower($haystack)) to warrant its inclusion in the PHP core.
- Risk of RFC Failure: The debate over whether to include a case-insensitive version, particularly with the complexities of ASCII vs. UTF-8 case folding, was a contentious topic that could have jeopardised the entire str_contains RFC from passing. The primary goal was to get a simple, much-needed function into the core.
Now that str_contains is a stable and widely used function in the PHP core, adding a case-insensitive version seems to me to be a logical next step. It creates a complete and consistent set of functions, mirroring the relationships between strpos -> stripos and strstr -> stristr. While the ASCII-only folding remains a limitation, this behaviour is consistent with its sibling functions, providing a predictable and familiar experience for developers.
Having a UTF-8 supported version of this suite of functions that matches on the lower/upper case variant of each Unicode code point should of course be a goal, but I believe the inclusion of this function in its current form, aligned with its siblings, is better than not having the function at all.
Backward Incompatible Changes
This RFC proposes the addition of a new function, so it does not introduce any backward-incompatible changes.
Proposed PHP Version(s)
Next PHP 8.x (8.5).
Proposed Voting Choices
Yes or no vote. 2/3 required to pass.
Patches and Tests
Implementation
After the project is implemented, this section should contain
- the version(s) it was merged into
- a link to the git commit(s)
- a link to the PHP manual entry for the feature
- a link to the language specification section (if any)
References
Prior discussion in May 2025: https://externals.io/message/127504
Original str_contains RFC: https://wiki.php.net/rfc/str_contains
Original str_contains discussion: https://externals.io/message/108562
Rejected Features
UTF-8 Support
This RFC intentionally omits support for full UTF-8 case folding. The primary goal is to provide a direct, case-insensitive companion to the existing str_contains function, thereby achieving feature parity with other core string functions that operate on ASCII case folding (e.g., stripos, stristr). Introducing multibyte-aware functionality would be a significant extension beyond this scope and is better suited for a separate, more comprehensive proposal regarding multibyte string handling.
stri_contains Naming
The name str_icontains was chosen over stri_contains to maintain consistency with the precedent set by str_ireplace.