Signature
str_replace(array|string $search, array|string $replace, string|array $subject, int &$count = null): string|arrayPurpose
str_replace() finds every occurrence of a fixed piece of text and substitutes another piece of text. It does no pattern matching. The needle is compared literally, byte for byte, and the match is case-sensitive. It suits template placeholders, removing unwanted characters, normalizing separators, or swapping known words. When you need patterns, use preg_replace(). When you need case-insensitive matching, use str_ireplace().
Signature
Parameters and defaults
$search: the needle. It can be one string or an array of needles.$replace: the replacement. It can be one string or an array of replacements.$subject: the haystack. It can be a string, or an array whose entries are each processed.$count: optional, passed by reference. If you supply a variable, PHP stores the total number of replacements performed in it. Without it, no count is reported.
When $search and $replace are both arrays, the values are paired by position, first to last. If $replace has fewer entries than $search, the missing replacements are treated as empty strings. If $search is an array and $replace is a single string, that string is used for every needle. The reverse combination, a string needle with an array of replacements, makes no sense and is rejected with a TypeError.
Return value and failure cases
The function returns a string when $subject is a string, and an array when $subject is an array. In the array case the keys are preserved and each entry is replaced individually. The original subject is never modified; you must use the returned value. If nothing matches, you get an equivalent value back and the count is 0. An empty search string is not an error; it simply produces no replacement for that needle. Passing argument types the signature does not allow raises a TypeError.
Example 1: a basic replacement with a count
The count is the number of replacements, not the number of changed strings.
$count = 0;
$result = str_replace("cat", "dog", "cat sat with a cat", $count);
echo json_encode(["result" => $result, "count" => $count], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), PHP_EOL;{"result":"dog sat with a dog","count":2}
Example 2: arrays of needles and the ordering effect
With array needles, PHP applies the pairs one after another to the result of the previous step. That means a value inserted by an earlier pair can be matched again by a later pair. In the first call below, A becomes B, then that B becomes C, then D. In the second call the replacement array is shorter, so b is replaced by an empty string.
$search = ['A', 'B', 'C'];
$replace = ['B', 'C', 'D'];
echo str_replace($search, $replace, 'A'), PHP_EOL;
echo str_replace(['a', 'b'], ['1'], 'aabbc'), PHP_EOL;D 11c
Example 3: an array subject and case sensitivity
When the subject is an array, every entry is searched and the keys stay the same. The count is the total across all entries. Notice that Apple with a capital letter is left alone, because matching is case-sensitive.
$items = ['name' => 'Red Apple', 'note' => 'red apple', 'other' => 'pear'];
$result = str_replace('apple', 'plum', $items, $count);
echo json_encode($result, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), PHP_EOL;
echo $count, PHP_EOL;{"name":"Red Apple","note":"red plum","other":"pear"}
1
Edge cases
- Chained replacements. Because array pairs are applied in order, the output of one pair is the input of the next. Order your arrays deliberately. For example, when normalizing line endings, search for
\r\nbefore\nand\r, so a Windows line break is not converted twice. - Overlapping needles. If one needle is a prefix of another, place the longer needle first, or the shorter one may consume part of it.
- Counting.
$countaccumulates over every needle and every array entry, so it can be larger than the number of subject entries. - Binary safety. The function works on raw bytes, so it is safe for data containing null bytes. It does not understand multibyte characters; it only matches the exact byte sequence you give it.
- No match. The subject comes back unchanged and
$countis set to0.
Common mistakes
- Ignoring the return value. Calling
str_replace('a', 'b', $text);on its own statement changes nothing. Assign the result:$text = str_replace('a', 'b', $text);. - Expecting case-insensitive matching.
Appleandappleare different needles. Usestr_ireplace()when case should not matter. - Using it for patterns. Wildcards or character classes are treated as literal text. Use
preg_replace()for those. - Forgetting cascading. Swapping two words with
str_replace(['a', 'b'], ['b', 'a'], $s)does not swap them: everything ends up as one letter. For a true simultaneous swap,strtr()with an array is the better tool. - Passing an array of replacements for a string needle. This combination is invalid and throws a
TypeError. - Reading
$countas a boolean. It holds a number of replacements, so compare it to0when you need to know whether anything changed.
Related functions
str_ireplace(): the case-insensitive version.substr_replace(): replaces text within a given position range.preg_replace(): replaces by regular expression.strtr(): translates characters or replaces substrings without re-scanning replaced text.
Recap
str_replace() performs literal, case-sensitive, left-to-right replacement on a string or on every entry of an array, and returns a new value of the same kind. Use the optional $count to learn how many replacements happened, keep the order of array pairs in mind, and reach for strtr(), str_ireplace() or preg_replace() when your needs go beyond a simple literal swap.
Tested examples
$count = 0;
$result = str_replace("cat", "dog", "cat sat with a cat", $count);
echo json_encode(["result" => $result, "count" => $count], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), PHP_EOL;{"result":"dog sat with a dog","count":2}
$search = ['A', 'B', 'C'];
$replace = ['B', 'C', 'D'];
echo str_replace($search, $replace, 'A'), PHP_EOL;
echo str_replace(['a', 'b'], ['1'], 'aabbc'), PHP_EOL;D 11c
$items = ['name' => 'Red Apple', 'note' => 'red apple', 'other' => 'pear'];
$result = str_replace('apple', 'plum', $items, $count);
echo json_encode($result, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), PHP_EOL;
echo $count, PHP_EOL;{"name":"Red Apple","note":"red plum","other":"pear"}
1