【问题标题】:Search PHP array of arrays using an array value and then update other array values in the matching array使用数组值搜索 PHP 数组数组,然后更新匹配数组中的其他数组值
【发布时间】:2016-05-18 06:10:47
【问题描述】:

我有一个字符串存储在 WordPress MySQL 数据库元字段中,作为数组数组的序列化字符串,如下所示:

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:"";}}

当我反序列化上面的那个字符串时,它看起来像下面这样......

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' => '',
  ),
)

基于上面的这个数组。我希望能够搜索具有ab-variation-letter' => 'C' 的数组,然后能够更新该匹配数组上的任何其他数组键值。完成后,我需要重新序列化回字符串,以便再次将其保存回数据库表。


我想在下面构建这个 PHP 函数,以便能够获取我的数组数组的序列化字符串,并在这些数组中搜索一个键/值与传入的 $array_key 字符串匹配的数组,然后更新另一个键值相同的数组,然后重新序列化整个东西。

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

}

最终结果应该允许我找到键为 'ab-variation-letter' === 'C' 的数组,并使用键 'ab-variation-title' 更新该匹配数组中的键/值,并将其当前值从 'ccccc' 更新为 'new value',然后重新将整个数组数组序列化回原始字符串,仅更新更新的数组数据/

【问题讨论】:

  • 然后能够更新该匹配数组上的任何其他数组键值不明白。

标签: php arrays serialization


【解决方案1】:

也许将一个可以利用调用自身的递归函数放在一起会派上用场:

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;
}

使用上述函数,您可以传递源数组 ($arr)、您要查找的键 ($whereKey)、它应该匹配的值 ($whereValue) 和替换值 (@ 987654325@)。

如果$replacement 是一个数组,我有一个array_replace_recursive 来执行递归替换,允许您传递您想要对数组进行的更改。例如,在您的情况下:

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

如果您不希望更改发生在任何嵌套子数组的下方,您可以将其替换为 array_recursive

使用该函数时,直接修改$data数组。该函数的结果是该值的键路径的联合字符串,在这种情况下:

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

如果你echo print_r($data, true),你会得到预期的结果:

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( ... )
)

【讨论】:

    【解决方案2】:

    在玩弄了下面的这段代码后,我得到了它。其他版本也开放谢谢

    $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;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-03-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-19
      • 1970-01-01
      • 2019-03-04
      • 2018-04-24
      相关资源
      最近更新 更多