str_replace
Replaces all occurrences of a search string with a replacement string in a string or array.
str_replace(array|string $search, array|string $replace, string|array $subject, int &$count = null): string|array- Added in PHP 4.0
Parameters
| Parameter | Type | Description |
|---|---|---|
$search | array|string | The value or values to search for. An array designates multiple needles. |
$replace | array|string | The replacement value or values. If search is an array and replace is a string, every needle is replaced by that string. |
$subject | string|array | The string or array of strings to search in. An array subject yields an array result with keys preserved. |
$countoptional | int= null | If supplied, set by reference to the number of replacements performed. |
Return value
string|arrayThe subject with all matches replaced. Returns an array when subject is an array, otherwise a string.
Errors
Throws a TypeError if search or replace is an array where the other argument's type makes the pairing invalid; no exceptions in normal use.
str_replace swaps every exact occurrence of a needle for a replacement. It works on a single string or on an array of strings, and both the needle and the replacement can themselves be arrays for bulk substitution.
When to reach for it
It is the default choice for literal text substitution: filling placeholders in a template, normalising line endings, stripping a known prefix, or sanitising a filename. Prefer it over preg_replace whenever the search text is fixed — it is faster and there is nothing to escape.
What trips people up
The order of operations. Replacements are applied left to right over the whole subject, one needle at a time, and each pass sees the output of the previous one. Replacing ['a','b'] with ['b','c'] turns a into c, because the b you just inserted is matched by the second rule. When needles and replacements overlap, use strtr with an associative array: it scans once and never revisits inserted text.
Two smaller gotchas: if search is longer than replace, the extra needles are replaced with an empty string; and matching is case-sensitive, so str_ireplace is the one you want for user-entered text.
Example
When to use it
- Fill named placeholders in an email or SMS template
- Normalise Windows CRLF line endings to LF before storing text
- Strip a fixed prefix or file extension from a list of names
- Escape or remove a set of characters from a generated filename
Frequently asked questions
What is the difference between str_replace and preg_replace?
str_replace matches literal text, preg_replace matches a regular expression. Use str_replace when the search string is fixed — it is faster and needs no escaping; reach for preg_replace only when you need a pattern.
Why does str_replace replace something it just inserted?
Because it applies needles in order and each pass runs over the result of the previous one. Use strtr with an associative array when replacements could match each other; it replaces in a single pass.
How do I make str_replace case-insensitive?
Use str_ireplace, which matches regardless of case. Note that it still inserts the replacement exactly as written, so the original capitalisation is not preserved.
More examples
The left-to-right chaining trap
The first line prints "c c": the a became b, and the second rule then rewrote that b as c. strtr on the next line does a single pass and correctly prints "b c". The third line collapses three needles into one replacement string, and the fourth shows the leftover rule — z has no matching replacement, so it is replaced with an empty string.
<?php
$s = 'a b';
echo str_replace(['a', 'b'], ['b', 'c'], $s), "\n";
echo strtr($s, ['a' => 'b', 'b' => 'c']), "\n";
echo str_replace(['one', 'two', 'three'], 'N', 'one two three'), "\n";
echo str_replace(['x', 'y', 'z'], ['1', '2'], 'x y z'), "\n";Normalising line endings and counting changes
CRLF is listed before a bare CR so the two-byte sequence is consumed first; reversing the order would turn every CRLF into two newlines. The count reports two replacements and the final line confirms the text splits into four clean lines.
<?php
$text = "line one\r\nline two\rline three\nline four";
$normalised = str_replace(["\r\n", "\r"], "\n", $text, $n);
var_dump($normalised);
echo "changed: {$n}\n";
echo 'lines: ', count(explode("\n", $normalised)), "\n";
Discussion