1

This is quite basic, but I am missing a puzzle piece.

I have a multidimensional PHP array that - among other things - contains some strings. I would like to translate special strings in this array based on a translation table or array in PHP.

$r = array(
    0 => 'something',
    1 => array(
       'othertext' => '1000 {{animals}} and {{cars}}',
       'anytext' => '400 {{cars}}',
    )
);

In $r, now I would like to replace {{animals}} with another string that is stored in a separate array.

Here it is:

$translations = array(
    'animals' => array('Tiere','animaux','bestie'),
    'cars' => array('Autos','voitures','macchine'),
);

Now let's set the language / column we want to look up

$langId = 0;

And now, take $r, look for all key that are wrapped in {{}}, look them up in $translations and replace them with key[$langId], so in return we get:

$r = array(
    0 => 'something',
    1 => array(
       'othertext' => '1000 Tiere',
       'anytext' => '400 Autos',
    )
);

ehm... how's that done?

PS: the marker {{}} is random, could be anything robust

Urs
  • 4,984
  • 7
  • 54
  • 116
  • 1
    You may want to do a preg_replace_callback() but possibly do it to the final output of the string(s) not as they sit in the array...just a thought. – Rasclatt Jan 15 '16 at 15:15
  • Something like this? http://stackoverflow.com/a/11174818/160968 – Urs Jan 15 '16 at 15:22
  • Yeah you parse final string and calculate the replacements in the callback function – Rasclatt Jan 15 '16 at 15:24
  • Unless you need to feed the fixed arrays into something else as a raw array, there is no need to make some algorithm to pre-fill them in the array. If you output the string in the end, you have the flexibility to combine different sources other than just your formatted array and it will replace everything in one shot as it outputs to the browser. So you can take a string: `$str = 'Red {{cars}} are my favorite.';` and combine it with the output of your array: `$final = "There are ".$r[1]['anytext']." on the lot. {$str}";` Then you `preg_replace_callback()` on `$final`. – Rasclatt Jan 15 '16 at 17:07
  • 1
    This is also the case if you get into nested arrays, then you have to do a recursive function just to dig down to find the replacements...it would just be easier to replace the final output in my opinion. – Rasclatt Jan 15 '16 at 17:09
  • You are right! I had been looking at str_replace and it said it would work on arrays too. The thing is I need to pass the array to another function afterwards. I could just do serialize(), then preg_replace (as in @biraa 's answer) or preg_replace_callback() as you suggest, and then unserialize again. I would have to pick other markers probably – Urs Jan 16 '16 at 08:29

1 Answers1

2

I was able to get the output you expected using the following code. Try it and tell me if it worked for you or not:

<?php
$r = array(
    0 => 'something',
    1 => array(
       'othertext' => '1000 {{animals}} and {{cars}}',
       'anytext' => '400 {{cars}}',
    )
);

$translations = array(
    'animals' => array('Tiere','animaux','bestie'),
    'cars' => array('Autos','voitures','macchine'),
);

$langId = 0;
$pattern = "/\{\{[a-zA-Z]+\}\}/";

for($t=0; $t<count($r); $t++) {
    $row = $r[$t];
    if(!is_array($row))
        continue;

    foreach($row as $key=>$value) {
    if(preg_match_all($pattern, $value, $match, PREG_SET_ORDER)) {
        for($i = 0; $i < count($match); $i++) {
            //remove {{ & }} to get key
            $k = substr($match[$i][0], 2, strlen($match[$i][0])-4); 
            $replacer = $translations[$k][$langId];
            $value = str_replace($match[$i][0], $replacer, $value);
            $r[$t][$key] = $value;
        }
     }
   }
}
?>
Urs
  • 4,984
  • 7
  • 54
  • 116
birraa
  • 430
  • 1
  • 4
  • 15
  • It works! what do you think about the unserialize idea above? – Urs Jan 16 '16 at 08:29
  • Ah no it doesn't. Try 'othertext' => '1000 {{animals}} and {{cars}}', – Urs Jan 16 '16 at 08:30
  • It will output 1000 Tiere and Tiere – Urs Jan 16 '16 at 10:31
  • That is because I assumed it will have only one pattern to be replaced in each case as per your example. Checked the edited version which does not make such assumption. – birraa Jan 17 '16 at 10:03
  • Ah, so the core of is `preg_match_all`, right? Awesome! Thanks a bunch – Urs Jan 17 '16 at 21:51
  • 1
    Yes, preg_match_all() will get you all the texts that match the pattern. Then you can replace them all. – birraa Jan 18 '16 at 06:51
  • I found a nice tutorial on preg functions: http://www.linuxonly.nl/docs/27/49_Introduction.html – Urs Feb 28 '16 at 19:12