====== 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. * Yes * No ===== Patches and Tests ===== https://github.com/php/php-src/pull/18705 ===== 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.