如何将后置数据从非序列化转换为序列化?

时间:2020-01-16 作者:WebElaine

我正在替换以前用ACF设置并单独保存的两个字段。而不是那些,我想有一个系列化的Posteta。

所以,我要从

meta_key: old_key_1, meta_value: value_1
meta_key: old_key_2, meta_value: value_2

meta_key: new_meta_key, meta_value: a:2:{i:0;s:7:"value_1";i:1;s:7:"value_2";}
(我不是在查询这些内容,只是在单个帖子上显示,所以我更喜欢在数据库中有一个条目来保存每个帖子的meta。)因为我有几百篇文章要更新,所以我想通过编程的方式来完成这项工作,无论是在phpMyAdmin还是PHP中,但我不确定要运行什么查询。

Question 1 - this part is solved

如何更新field_1 是否包含序列化数据?

我添加了一个临时函数来更新元键并序列化第一个字段的元值:

<?php add_action(\'admin_init\', \'convert_double_meta\');
function convert_double_meta() {
    global $wpdb;
    $first_records = $wpdb->get_results(
        $wpdb->prepare("SELECT * FROM wp_postmeta WHERE meta_key = \'field_1\'")
    );
    foreach($first_records as $record) {
        // Serialize the meta value by passing it as an array
        update_post_meta($record->post_id, \'field_1\', array(0 => $record->meta_value));
        // Update the meta key
        $updated = $wpdb->update(
            \'wp_postmeta\',
            array(
                \'meta_key\' => \'new_meta_key\'
            ),
            array(\'meta_id\' => $record->meta_id)
        );
    }
} ?>

Question 2 - still unsolved

如何从中合并数据old_key_2 输入的序列化值new_meta_key? (如果有更简单的方法来完成这一切,我愿意采取不同的步骤来实现相同的结果。)

1 个回复
最合适的回答,由SO网友:Antti Koskinen 整理而成

我可能会采取另一种方法,在数据已经合并之后,让序列化在最后发生,如下面的示例所示。

所以首先查询两个旧密钥的元数据。然后将旧数据合并到以post ID为键的数组(常规或关联)中。然后在循环中使用生成的数组,该循环使用update_post_meta 让它处理序列化。最后是一些$wpdb 查询以使用旧密钥从数据库中擦除数据。

这可能不是最有效的方法,但如果您只执行一次,那么我认为这并不重要。

add_action(\'admin_init\', \'convert_meta_data\');
function convert_meta_data() {    
  $data = query_old_data( old_keys() );

  $data = merge_old_data( $data ) ;

  update_meta_with_new_key( $data, \'new_meta_key\' );

  delete_data_with_old_keys( old_keys() );
}

function old_keys() {
  return array(
    \'field_1\',
    \'field_2\'
  );
}

function query_old_data( array $old_keys ) {
  $data = array();
  global $wpdb;
  foreach( $old_keys as $old_key ) {
    $data[$old_key] = $wpdb->get_results(
      $wpdb->prepare("SELECT * FROM wp_postmeta WHERE meta_key = {$old_key}")
    );
  }  
  return $data;
}

function merge_old_data( array $data ) {
  $out = array();
  foreach ($data as $old_key => $records) {
    foreach ($records as $record) {
      $out[$record->post_id][$old_key] = maybe_unserialize($record->meta_value); 
      // I don\'t know what happens, if some of the data in the resulting array was serialized and some not, so lets make sure everything is unserialized     
    }    
  }
  return $out;
}

function update_meta_with_new_key( array $data, string $key ) {
  foreach ($data as $post_id => $meta_array) {
    update_post_meta($post_id, $key, $meta_array); // handles serialization
  }
}

function delete_data_with_old_keys( array $old_keys ) {
  // not too sure about this
  $sql = "meta_key = " . implode(\'OR \', $old_keys);
  global $wpdb;
  $wpdb->delete( \'wp_postmeta\', $sql);
}

相关推荐

列出分类法:如果分类法没有POST,就不要列出分类法--取决于定制的POST-META?

这可能很难解释,我不知道是否有解决办法!?我有一个名为“wr\\u event”的自定义帖子类型和一个名为“event\\u type”的分层自定义分类法。自定义帖子类型有一个元框,用于event_date 并且与此帖子类型关联的所有帖子都按以下方式排序event_date. 我在循环中有一个特殊的条件来查询event_date 已经发生了-在这种情况下,它没有显示,但只列在我的档案中。就像你可以使用wp_list_categories() 我编写了一个自定义函数,它以完全相同的方式列出所有分类术语。现在