I have an object that looks like this:
{
"message": {
"attachment": {
"payload": {
"buttons": [
{
"title": "View",
"type": "web_url",
"url": "https://google.com"
}
],
"template_type": "button",
"text": "You have ##likes_count## new likes in your item."
},
"type": "template"
}
}
}
I want to replace the value of the "text" property with a specific value, say "5". I tried doing str_replace('##likes_count##', '5', $message)
but it does not seem to find the string to replace. I can loop through that object and find the "text" property and replace its value but the location of that property is not permanent. Sometimes it's under "buttons" or "attachment".
Is there a way to look for the "text" property anywhere in the object and replace its value? Any help would be appreciated :)
Edit: I know it's a string. What I mean is that I have an object that has a structure like that. I can convert that object into a string and do str_replace but I need to convert it back into an object which I would rather not do.
Firstly, there is no PHP object involved. Just JSON data returned from some remote endpoint.
One can go through a route shown by @Michał Szczech - ie to let the data be in a string format and replace all occurrences of the needle there.
Or you can go through a route of decoding the JSON string into a PHP array/object and do the replacement there. This approach has an advantage of replacing the value only in case its key is called text
.
Consider a script like this:
<?php
/**
* Replace a value stored deep within a nested array.
* Only in case its key is called 'text'
* Use pattern defined as a global constant `PATTERN`
*
* @param array $hayStack
* @param string $needle
* @param string $replaceString
*/
function deepReplace(&$hayStack, $needle, $replaceString)
{
foreach ($hayStack as $key => &$value) {
if ($key === $needle) {
$hayStack[$key] = preg_replace(
'/' . PATTERN . '/',
$replaceString,
$value
);
}
if (is_array($value)) {
deepReplace($value, $needle, $replaceString);
}
}
}
define('PATTERN', '##likes_count##');
// data provided from your source in JSON format
$data = '
{
"message": {
"attachment": {
"payload": {
"buttons": [
{
"title": "View",
"type": "web_url",
"url": "https://google.com"
}
],
"template_type": "button",
"text": "You have ##likes_count## new likes in your item."
},
"type": "template"
}
}
}
';
// decode JSON into a nested PHP array
$nestedArray = json_decode($data, true);
// recursively replace occurrences of '##likes_count##' within 'text' key
deepReplace($nestedArray, 'text', 5);
// replacement complete - go on processing it as you like..
// I am just printing the encoded string to prove it works
echo json_encode($nestedArray, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES);
The script prints a string like this:
{
"message": {
"attachment": {
"payload": {
"buttons": [
{
"title": "View",
"type": "web_url",
"url": "https://google.com"
}
],
"template_type": "button",
"text": "You have 5 new likes in your item."
},
"type": "template"
}
}
}
You have to remember that you have to assign the result of str_replace
as shown below:
$message = '"message": {
"attachment": {
"type": "template",
"payload": {
"template_type": "button",
"text": "You have ##likes_count## new likes in your item.",
"buttons": [
{
"type": "web_url",
"title": "View",
"url": "https://google.com"
}
]
}
}
}';
$message = str_replace('##likes_count##', '5', $message);
print_r($message);