Signature
str_ireplace(
array|string $search,
array|string $replace,
string|array $subject,
int &$count = null
): string|arrayPurpose
str_ireplace() finds every occurrence of a fixed piece of text inside a string and swaps it for another value, ignoring upper and lower case while matching. It is the case-insensitive sibling of str_replace(). Use it for template placeholders, simple word substitutions and cleanup of user-supplied labels where the capitalisation of the match does not matter.
The function does not understand patterns. If you need wildcards, anchors or captures, use preg_replace() with the i modifier instead.
Signature
Parameters and defaults
$search: the needle. It can be a single string or an array of needles.$replace: the replacement text. It can be a string, or an array that lines up with an array of needles.$subject: the haystack. A string gives a string back; an array is processed entry by entry and gives an array back.$count: optional, passed by reference. When supplied, it is set to the total number of replacements made. It has no effect on the result and defaults tonull.
When $search and $replace are both arrays, the values are paired in order. If $replace is shorter, the missing replacements are treated as empty strings. If $search is an array and $replace is a string, that one string is used for every needle. The reverse, a string needle with an array replacement, is not meaningful and should be avoided.
Return value and failure cases
The function returns a string when $subject is a string and an array when $subject is an array. It does not return false when nothing matches; you simply get the original value back and $count is 0. Passing arguments of unsupported types follows normal PHP 8 type rules and raises a TypeError.
Example 1: a basic placeholder
The match ignores case, but the replacement is inserted exactly as written.
$result = str_ireplace("%body%", "black", "<body text=%BODY%>");
echo $result . "\n";<body text=black>
Example 2: array subject and the count argument
When the subject is an array, every entry is processed and the keys are kept. The count adds up replacements across all entries and all needles.
$count = 0;
$result = str_ireplace(["red", "BLUE"], "color", ["Red and blue", "RED", "green"], $count);
echo json_encode(["result" => $result, "count" => $count], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
echo "\n";{"result":["color and color","color","green"],"count":3}
Example 3: ordering and short replacement arrays
Needles are handled from first to last, and each pass works on the output of the previous one. That means a value inserted earlier can be replaced again later. A short $replace array fills in empty strings.
$chained = str_ireplace(["A", "B"], ["B", "C"], "a");
$short = str_ireplace(["x", "y"], ["1"], "X-Y-z");
echo json_encode(["chained" => $chained, "shortReplace" => $short], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
echo "\n";{"chained":"C","shortReplace":"1--z"}
In the chained case, a first becomes b, and then that new b matches the second needle and becomes C. This surprises people who expect the two pairs to be applied independently.
Edge cases
- Non-ASCII text: since PHP 8.2, case folding no longer depends on the locale set with
setlocale(). Only ASCII letters are folded, and other bytes are compared by their byte value. SoÉandéare not treated as the same character. For true multibyte case-insensitive replacement, usepreg_replace()with theiumodifiers. - Binary safety: the function is binary-safe, so strings containing null bytes are handled as ordinary data.
- Replacement casing: the replacement is never adapted to the case of the matched text. Replacing
WorldwithPHPinWORLDgivesPHP, not an upper-cased variant. - No match: the subject comes back unchanged and
$countis0.
Common mistakes
- Forgetting that the search is case-insensitive and accidentally replacing words you wanted to keep, such as
Applethe brand versusapplethe fruit. Usestr_replace()when case matters. - Relying on array pairs being independent. If an earlier replacement produces text that a later needle matches, it will be replaced again. Reorder the needles, or use
strtr()with an array, which does not rescan replaced text. - Expecting
$countto be per entry. With an array subject it is a single running total. - Using it for pattern matching. It treats the search value literally, so characters such as
.or*have no special meaning. - Assuming it handles accented letters the way a locale-aware function would. In PHP 8.2 and later it does not.
Related functions
str_replace(): the case-sensitive version.preg_replace(): pattern-based replacement, with animodifier for case-insensitivity.strtr(): translates characters or replaces substrings without rescanning inserted text.
Recap
str_ireplace() performs literal, ASCII case-insensitive replacement on a string or an array of strings. Remember that arrays are applied in order, that the replacement text is inserted as given, that $count reports the total number of replacements, and that non-ASCII letters are not case-folded.
Tested examples
$result = str_ireplace("%body%", "black", "<body text=%BODY%>");
echo $result . "\n";
<body text=black>
$count = 0;
$result = str_ireplace(["red", "BLUE"], "color", ["Red and blue", "RED", "green"], $count);
echo json_encode(["result" => $result, "count" => $count], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
echo "\n";
{"result":["color and color","color","green"],"count":3}
$chained = str_ireplace(["A", "B"], ["B", "C"], "a");
$short = str_ireplace(["x", "y"], ["1"], "X-Y-z");
echo json_encode(["chained" => $chained, "shortReplace" => $short], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
echo "\n";
{"chained":"C","shortReplace":"1--z"}