0

I have a string stored in WordPress MySQL database Meta field as serialized string of array of arrays like this:

a:4:{i:0;a:8:{s:19:"ab-variation-letter";s:1:"B";s:18:"ab-variation-title";s:6:"bbbbbb";s:28:"ab-variation-wysiwyg-editor-";s:12:"bbbbbbbbbbbb";s:29:"ab-variation-conversion-count";s:0:"";s:18:"ab-variation-views";s:0:"";s:23:"ab-variation-start-date";s:0:"";s:21:"ab-variation-end-date";s:0:"";s:19:"ab-variation-winner";s:0:"";}i:1;a:8:{s:19:"ab-variation-letter";s:1:"C";s:18:"ab-variation-title";s:5:"ccccc";s:28:"ab-variation-wysiwyg-editor-";s:17:"ccccccccccccccccc";s:29:"ab-variation-conversion-count";s:0:"";s:18:"ab-variation-views";s:0:"";s:23:"ab-variation-start-date";s:0:"";s:21:"ab-variation-end-date";s:0:"";s:19:"ab-variation-winner";s:0:"";}i:2;a:8:{s:19:"ab-variation-letter";s:1:"D";s:18:"ab-variation-title";s:8:"dddddddd";s:28:"ab-variation-wysiwyg-editor-";s:1:"d";s:29:"ab-variation-conversion-count";s:0:"";s:18:"ab-variation-views";s:0:"";s:23:"ab-variation-start-date";s:0:"";s:21:"ab-variation-end-date";s:0:"";s:19:"ab-variation-winner";s:0:"";}i:3;a:8:{s:19:"ab-variation-letter";s:1:"E";s:18:"ab-variation-title";s:8:"eeeeeeee";s:28:"ab-variation-wysiwyg-editor-";s:30:"eeeeeee eeeeeeeeeeeee eeeeeeee";s:29:"ab-variation-conversion-count";s:0:"";s:18:"ab-variation-views";s:0:"";s:23:"ab-variation-start-date";s:0:"";s:21:"ab-variation-end-date";s:0:"";s:19:"ab-variation-winner";s:0:"";}}

When I unserialize that string above it looks like this below...

array (
  0 => 
  array (
    'ab-variation-letter' => 'B',
    'ab-variation-title' => 'bbbbbb',
    'ab-variation-wysiwyg-editor-' => 'bbbbbbbbbbbb',
    'ab-variation-conversion-count' => '',
    'ab-variation-views' => '',
    'ab-variation-start-date' => '',
    'ab-variation-end-date' => '',
    'ab-variation-winner' => '',
  ),
  1 => 
  array (
    'ab-variation-letter' => 'C',
    'ab-variation-title' => 'ccccc',
    'ab-variation-wysiwyg-editor-' => 'ccccccccccccccccc',
    'ab-variation-conversion-count' => '',
    'ab-variation-views' => '',
    'ab-variation-start-date' => '',
    'ab-variation-end-date' => '',
    'ab-variation-winner' => '',
  ),
  2 => 
  array (
    'ab-variation-letter' => 'D',
    'ab-variation-title' => 'dddddddd',
    'ab-variation-wysiwyg-editor-' => 'd',
    'ab-variation-conversion-count' => '',
    'ab-variation-views' => '',
    'ab-variation-start-date' => '',
    'ab-variation-end-date' => '',
    'ab-variation-winner' => '',
  ),
  3 => 
  array (
    'ab-variation-letter' => 'E',
    'ab-variation-title' => 'eeeeeeee',
    'ab-variation-wysiwyg-editor-' => 'eeeeeee eeeeeeeeeeeee eeeeeeee',
    'ab-variation-conversion-count' => '',
    'ab-variation-views' => '',
    'ab-variation-start-date' => '',
    'ab-variation-end-date' => '',
    'ab-variation-winner' => '',
  ),
)

based on this array of arrays above. I want to be able to search for the array that has ab-variation-letter' => 'C' and then be able to update any of the other array key values on that matching array. When done I will need to re-serialize back into a string so I can save it back to the Database table again.


I want to build this PHP function below to be able to take my serialized string of array of arrays and search those arrays for an array that has a key/value matching the passed in $array_key string and then update another keyvalue in that same array and then reserialize the whole thing again.

function updateAbTestMetaData($post_id, $meta_key, $meta_value, $array_key, $new_value){

    //get serialized meta from DB
    $serialized_meta_data_string = 'a:4:{i:0;a:8:{s:19:"ab-variation-letter";s:1:"B";s:18:"ab-variation-title";s:6:"bbbbbb";s:28:"ab-variation-wysiwyg-editor-";s:12:"bbbbbbbbbbbb";s:29:"ab-variation-conversion-count";s:0:"";s:18:"ab-variation-views";s:0:"";s:23:"ab-variation-start-date";s:0:"";s:21:"ab-variation-end-date";s:0:"";s:19:"ab-variation-winner";s:0:"";}i:1;a:8:{s:19:"ab-variation-letter";s:1:"C";s:18:"ab-variation-title";s:5:"ccccc";s:28:"ab-variation-wysiwyg-editor-";s:17:"ccccccccccccccccc";s:29:"ab-variation-conversion-count";s:0:"";s:18:"ab-variation-views";s:0:"";s:23:"ab-variation-start-date";s:0:"";s:21:"ab-variation-end-date";s:0:"";s:19:"ab-variation-winner";s:0:"";}i:2;a:8:{s:19:"ab-variation-letter";s:1:"D";s:18:"ab-variation-title";s:8:"dddddddd";s:28:"ab-variation-wysiwyg-editor-";s:1:"d";s:29:"ab-variation-conversion-count";s:0:"";s:18:"ab-variation-views";s:0:"";s:23:"ab-variation-start-date";s:0:"";s:21:"ab-variation-end-date";s:0:"";s:19:"ab-variation-winner";s:0:"";}i:3;a:8:{s:19:"ab-variation-letter";s:1:"E";s:18:"ab-variation-title";s:8:"eeeeeeee";s:28:"ab-variation-wysiwyg-editor-";s:30:"eeeeeee eeeeeeeeeeeee eeeeeeee";s:29:"ab-variation-conversion-count";s:0:"";s:18:"ab-variation-views";s:0:"";s:23:"ab-variation-start-date";s:0:"";s:21:"ab-variation-end-date";s:0:"";s:19:"ab-variation-winner";s:0:"";}}';

    //un-serialize meta data string
    $meta_data_arrays = unserialize($serialized_meta_data_string);

    // search array of arrays $meta_data_arrays for array that has a key == $array_key // 'ab-variation-letter' === 'D'

    // update the value of any other key on that matching array

    // re-serialize all the data with the updated data

}

The end result should allow me to find the array with key 'ab-variation-letter' === 'C' and update the key/value in that matching array with key 'ab-variation-title' and update its current value from 'ccccc' to 'new value' and then re-serialize the whole entire array of arrays back into the original string with only the updated array data updated/

1
  • then be able to update any of the other array key values on that matching array Not understand. Commented May 18, 2016 at 6:14

2 Answers 2

1

Perhaps throwing together a recursive function that can make use of calling itself could come in handy:

function replaceArrayKeyValue(array &$arr, $whereKey, $whereValue, $replacement) {
  $matched = false;
  $keys = array_keys($arr);

  for ($i = 0; $i < count($keys); $i++)
  {
    $key = $keys[$i];
    if (is_string($arr[$key])) {
      if ($key === $whereKey && $arr[$key] === $whereValue) {
        if (is_array($replacement)) {
          $arr = array_replace_recursive($arr, $replacement);
        } else {
          $arr[$key] = $replacement;
        }
        $matched = $key;
        break;
      }
    } else if (is_array($arr[$key])) {
      $m = replaceArrayKeyValue($arr[$key], $whereKey, $whereValue, $replacement);
      if ($m !== false) {
        $matched = $key.'.'.$m;
        break;
      }
    }
    unset($key);
  }

  unset($keys);
  return $matched;
}

With the above function, you pass through the source array ($arr), the key you're looking for ($whereKey), the value that it should match ($whereValue) and the replacement value ($replacement).

If $replacement is an array, I've got a array_replace_recursive in place to perform a recursive replacement, allowing you to pass in the changes you'd like to make to the array. For example, in your case:

$data = unserialize(...);
$matchedKey = replaceArrayKeyValue($data, 'ab-variation-letter', 'C', [
    'ab-variation-title' => 'My New Title'
]);
$serialized = serialize($data);

You could replace this with array_recursive if you're not wanting the changes to occur further down any nested child arrays.

When using this function, the $data array is modified directly. The result of the function is a joint string of the key path to that value, in this case:

echo $matchedKey; // Result: 1.ab-variation-letter

If you echo print_r($data, true), you get the intended result:

Array (
    [0] => Array( ... )
    [1] => Array
        (
            [ab-variation-letter] => C
            [ab-variation-title] => My New Title
            [ab-variation-wysiwyg-editor-] => ccccccccccccccccc
            [ab-variation-conversion-count] =>
            [ab-variation-views] =>
            [ab-variation-start-date] =>
            [ab-variation-end-date] =>
            [ab-variation-winner] =>
        )
    [2] => Array( ... )
    [3] => Array( ... )
)
Sign up to request clarification or add additional context in comments.

Comments

0

I got it working after some playing around with this code below. Open to other versions as well thanks

$serialized_meta_data_string = 'a:4:{i:0;a:8:{s:19:"ab-variation-letter";s:1:"B";s:18:"ab-variation-title";s:6:"bbbbbb";s:28:"ab-variation-wysiwyg-editor-";s:12:"bbbbbbbbbbbb";s:29:"ab-variation-conversion-count";s:0:"";s:18:"ab-variation-views";s:0:"";s:23:"ab-variation-start-date";s:0:"";s:21:"ab-variation-end-date";s:0:"";s:19:"ab-variation-winner";s:0:"";}i:1;a:8:{s:19:"ab-variation-letter";s:1:"C";s:18:"ab-variation-title";s:5:"ccccc";s:28:"ab-variation-wysiwyg-editor-";s:17:"ccccccccccccccccc";s:29:"ab-variation-conversion-count";s:0:"";s:18:"ab-variation-views";s:0:"";s:23:"ab-variation-start-date";s:0:"";s:21:"ab-variation-end-date";s:0:"";s:19:"ab-variation-winner";s:0:"";}i:2;a:8:{s:19:"ab-variation-letter";s:1:"D";s:18:"ab-variation-title";s:8:"dddddddd";s:28:"ab-variation-wysiwyg-editor-";s:1:"d";s:29:"ab-variation-conversion-count";s:0:"";s:18:"ab-variation-views";s:0:"";s:23:"ab-variation-start-date";s:0:"";s:21:"ab-variation-end-date";s:0:"";s:19:"ab-variation-winner";s:0:"";}i:3;a:8:{s:19:"ab-variation-letter";s:1:"E";s:18:"ab-variation-title";s:8:"eeeeeeee";s:28:"ab-variation-wysiwyg-editor-";s:30:"eeeeeee eeeeeeeeeeeee eeeeeeee";s:29:"ab-variation-conversion-count";s:0:"";s:18:"ab-variation-views";s:0:"";s:23:"ab-variation-start-date";s:0:"";s:21:"ab-variation-end-date";s:0:"";s:19:"ab-variation-winner";s:0:"";}}';

$update_on_key = 'ab-variation-title';
$ab_version = 'C';
$new_value = 'new variation title on variation C';

$new_data = updateMetaArrayData($serialized_meta_data_string, $update_on_key, $ab_version, $new_value);

echo '<pre>';
echo $new_data;


function updateMetaArrayData($serialized_meta_data_string, $update_on_key, $ab_version, $new_value){
    $new_meta_data_arrays = array();

    //un-serialize meta data string
    $meta_data_arrays = unserialize($serialized_meta_data_string);

    foreach($meta_data_arrays as $key => $value){
        $new_meta_data_arrays[$key] = $value;
        if(isset($value['ab-variation-letter']) && $value['ab-variation-letter'] == $ab_version){
            $new_meta_data_arrays[$key][$update_on_key] = $new_value;
        }
    }

    echo '<pre>';
    print_r($new_meta_data_arrays);

    $new_serialized_meta = serialize($new_meta_data_arrays);
    return $new_serialized_meta;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.