Str::replace

Replaces every occurrence of a value in a string, with optional case-insensitive matching.

Signature
Str::replace(string|iterable $search, string|iterable $replace, string|iterable $subject, bool $caseSensitive = true): string|string[]

Parameters

ParameterTypeDescription
$$searchstring|iterable<string>The value to look for, or a list of values applied one after another in order.
$$replacestring|iterable<string>The replacement, or a list positionally paired with $search. Missing entries are replaced with an empty string.
$$subjectstring|iterable<string>The string to search in. An iterable subject is converted to an array and the replacement is applied to each element.
$$caseSensitiveoptionalbool= trueWhen false, matching ignores case (str_ireplace instead of str_replace).

Return value

string|string[]The subject with every match replaced; an array when the subject is an array or other iterable.

Str::replace wraps str_replace and adds the one thing PHP's function has never had: a case-insensitivity flag you can pass conditionally instead of choosing between two function names. It also accepts any iterable — a Collection, a generator — for the search, replacement and subject, converting it to an array first.

Replacements are sequential, not simultaneous

With an array of needles, each pair is applied to the output of the previous one. That makes swapping two values impossible in a single call: replacing a with b and b with a turns ab into aa, because the freshly written b is still in the string when the second pair runs. Use strtr() with a map when you need one simultaneous pass.

The return type follows the subject

A string subject gives a string; an array or iterable subject gives an array with the same keys. Code that assumes a string will break the moment someone passes a Collection, so type the caller accordingly.

It is literal, not a pattern

Nothing here is a regular expression, so . and * match themselves. That is usually what you want; when it is not, use Str::replaceMatches or preg_replace.

Example

Try it yourself
Loading editor…
Press Run to execute the code.

When to use it

  • Substitute placeholders such as :name in a template string you control.
  • Rewrite a version number or path across a generated stub file.
  • Normalise inconsistent separators in a batch of imported values.

Frequently asked questions

How do I do a case-insensitive replace in Laravel?

Pass caseSensitive: false as the fourth argument. Str::replace('php', 'Laravel', 'PHP Framework', caseSensitive: false) matches regardless of case, which plain str_replace cannot do without switching to str_ireplace.

Why does replacing two values with each other produce the wrong result?

Array pairs are applied one after another rather than simultaneously, so the second replacement sees the output of the first. Use strtr($subject, ['a' => 'b', 'b' => 'a']), which matches every key against the original string in a single pass.

Can Str::replace use a regular expression?

No — the search is always a literal string, so characters like . and * match themselves. Use Str::replaceMatches($pattern, $replace, $subject) or preg_replace when you need a pattern.

More examples

Filling placeholders in a stub

Positional arrays are the right shape here because no replacement value can contain another placeholder, so the sequential application is harmless. This is exactly how Artisan's make: commands render their stubs.

Example · php
<?php

use Illuminate\Support\Str;

$stub = <<<'STUB'
namespace {{ namespace }};

class {{ class }} extends {{ parent }}
{
    //
}
STUB;

$rendered = Str::replace(
    ['{{ namespace }}', '{{ class }}', '{{ parent }}'],
    ['App\\Models', 'Invoice', 'Model'],
    $stub
);

echo $rendered, "\n";

// namespace App\Models;
//
// class Invoice extends Model
// {
//     //
// }

Case-insensitivity decided at runtime

Because the flag is a parameter rather than a different function name, the caller can decide at runtime without an if statement selecting between str_replace and str_ireplace. The first call misses the capitalised occurrence, which is the whole point of the comparison.

Example · php
<?php

use Illuminate\Support\Str;

function censor(string $text, array $words, bool $matchCase): string
{
    return Str::replace(
        $words,
        array_fill(0, count($words), '[redacted]'),
        $text,
        caseSensitive: $matchCase
    );
}

$text = 'The Secret plan is secret.';

echo censor($text, ['secret'], true), "\n";
// The Secret plan is [redacted].

echo censor($text, ['secret'], false), "\n";
// The [redacted] plan is [redacted].

The sequential-replacement trap in full

The first pair writes {second} into the string, and the second pair then rewrites that back to {first}, so both slots end up identical. strtr matches every key against the original string in one pass and never revisits what it has written.

Example · php
<?php

use Illuminate\Support\Str;

// Intent: swap the two placeholders.
$template = 'Hello {first}, meet {second}.';

$broken = Str::replace(
    ['{first}', '{second}'],
    ['{second}', '{first}'],
    $template
);

echo $broken, "\n";
// Hello {first}, meet {first}.

$fixed = strtr($template, [
    '{first}'  => '{second}',
    '{second}' => '{first}',
]);

echo $fixed, "\n";
// Hello {second}, meet {first}.

Discussion

  • Be the first to comment on this lesson.