17

How can I replace a sub string with some other string for all items of an array in PHP?

I don't want to use a loop to do it. Is there a predefined function in PHP that does exactly that?

How can I do that on keys of array?

6
  • 4
    why don't you want to use a loop? sounds more like a whim rather than sensible reason. Commented Feb 12, 2011 at 8:03
  • @edit: Use array_flip before it and after it on the array and leave the other code as is. Commented Feb 12, 2011 at 8:28
  • Possible duplicate of String replace all items in array PHP Commented Jun 6, 2016 at 22:04
  • 1
    Relevant pages with better clarity: Replace substring in column values of a 2d array and changing keys Recursively change keys in array Commented Apr 11, 2023 at 3:15
  • 1
    Even "How can I do that on keys of array?" is ambiguous. Do you want to change the keys or only change values for specific keys? Commented Apr 11, 2023 at 4:15

8 Answers 8

102

Why not just use str_replace without a loop?

$array = array('foobar', 'foobaz');
$out = str_replace('foo', 'hello', $array);
Sign up to request clarification or add additional context in comments.

4 Comments

When I try this with a decoded JSON array I get an error PHP Catchable fatal error: Object of class stdClass could not be converted to string I am very new to PHP, seems it's difficult to edit an array so far.
@Dennis: json_decode returns an object by default, not an array, unless you explicitly specify that you want an array.
This will not work on php 8.1 any more if your array contains more than one dimension, see: 3v4l.org/VgF8j#v8.1.17
@rubo77 well, that's exactly why I've voted to delete this page -- there is no minimal reproducible example. We don't know what data needs to be replaced. There is such a deficit of clarity that answers on this page are solving different problems. It may have high scoring posts, but this page has been sprayed with too many divergent answers -- several which are unexplained -- making this page not helpful for readers and not a good fit for Stack Overflow.
30
$array = array_map(
    function($str) {
        return str_replace('foo', 'bar', $str);
    },
    $array
);

But array_map is just a hidden loop. Why not use a real one?

foreach ($array as &$str) {
    $str = str_replace('foo', 'bar', $str);
}

That's much easier.

2 Comments

Ok, I tried the second option, but without & sign before $str and it didn't work. But why & sign, what does the & sign mean in this case?
The and-sign makes the variable a pointer to reach real array element in the loop
7

This is a very good idea that I found and used successfully:

function str_replace_json($search, $replace, $subject) 
{
    return json_decode(str_replace($search, $replace, json_encode($subject)), true);
}

It is good also for multidimensional arrays.

If you change the "true" to "false" then it will return an object instead of an associative array.

Source: Codelinks

3 Comments

It wouldn't work if you're trying to replace a bracket { or }.
this works fine on arrays, but if an array contains an element, that is an Object, it will convert the Object into an array
This answer will mutate any qualifying key and or value. It is also prone to producing invalid json thus breaking the script.
1
function my_replace_array($array,$key,$val){
    for($i=0;$i<count($array);$i++){
        if(is_array($array[$i])){
            $array[$i] = my_replace_array($array[$i],$key,$val);
        }else{
            $array[$i]=str_replace($key,$val,$array[$i]);
        }
    }
    return $array;
}

6 Comments

This recursive answer is missing its educational explanation.
Objects should be handled too
There isn't a whiff of "objects" in the vaguely asked question. @rubo77
"all items" can be objects too, which are not handled in this example.
The edit by @rubo77 invalidates this answer. Proof: 3v4l.org/bqQc7 For this reason, the edit should rolled back, the page closed, and the page be allowed to continue accumulating delete votes.
|
1

I am not sure how efficient this is, but I wanted to replace strings in a big multidimensional array and did not want to loop through all items as the array structure is pretty dynamic.

I first json_encode the array into a string.

Replace all the strings I want (need to use preg_replace if there are non-English characters that get encoded by json_encode).

json_decode to get the array back.

1 Comment

A word of caution to developers who are entertaining this advice: using str_replace() or preg_replace() on a json-encoded string will make all keys, values, and the json formatting characters vulnerable to mutation. There may be scenarios where this technique is safe, but this generalized advice should not be implemented as a general-use approach.
1

With array_walk_recursive()

function replace_array_recursive( string $needle, string $replace, array &$haystack ){
    array_walk_recursive($haystack,
        function (&$item, $key, $data){
        $item = str_replace( $data['needle'], $data['replace'], $item );
        return $item;
    },
        [ 'needle' => $needle, 'replace' => $replace ]
    );
}

1 Comment

Is return $item; actually necessary?
1

There is no predefined function anymore (since PHP 8.1). So this will replace in all elements, even if there are Objects:

<?php

class Arrays {
    /**
     * Replaces in all strings within a multidimensional array, even if objects are included
     * @param  string $search       search for this string
     * @param  string $replace_with replace with this string
     * @param  mixed $haystack        Array or Object to search in all elements
     * @return mixed               gives the same structure back
     */
    public static function replace_everywhere($search, $replace_with, $haystack) {
        if (is_array($haystack) or is_object($haystack)) {
            // Arrays and Objects
            foreach ($haystack as &$value) {
                $value = Arrays::replace_everywhere($search, $replace_with, $value);
            }
            return $haystack;
        } elseif (is_string($haystack)) {
            // replace in a string element
            return str_replace($search, $replace_with, $haystack);
        } else {
            // other datatypes (e.g. integer) stay untouched
            return $haystack;
        }
    }
}


// You can call this like e.g.
$a = array(true, 1, 'foo<bar', 'foo<baz', array("foo<loo"), (object) array('1' => 'foo<boo'));
$a = Arrays::replace_everywhere("<", "&lt;", $a);
var_export($a);

Example: https://3v4l.org/CDGvC#v8.2.5


If you want to replace array keys, I think that's another question with good answers like: recursively-change-keys-in-array

7 Comments

Rather vandalizing the question to suit only your answer, you should have asked a new question with a clear minimal reproducible example and self-answered it.
Adding a sample input is only a part of a minimal reproducible example. There is no desired output -- so the question remains Unclear (and should not have been reopened). By biasing the input data set to accommodate your answer, you have potentially invalidated earlier posted answers. Foul play.
Your are right, I edited the minimal example so that it fits to all answers.
Btw: I think "vandalizing" is something different. Here I just added am example, so this searchengine-famous question will become more clear what the author obviously intended
I find this page to be inappropriately famous. It represents some of the very worst questions on the site -- vague requirements, no mcve, no effort, clickbait title. Your answer is now an over-engineered solution that goes beyond calling str_replace() on a flat array. In other words, your answer is better suited to a different question.
|
0
$base = array('citrus' => array( "orange") , 'berries' => array("blackberry", "raspberry"), );
$replacements = array('citrus' => array('pineapple'), 'berries' => array('blueberry'));
$basket = array_replace_recursive($base, $replacements);
$basket = array_replace($base, $replacements);

1 Comment

This answer is missing its educational explanation. How does it work? In what situations will this technique not work? I know these answers, but researchers won't -- please be more generous with your contribution. The trouble with these old question that do not include sample data is that the scope is open to interpretation. I fear you are stretching the scope beyond the original post, but there is no way of knowing.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.