我正在替换以前用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
? (如果有更简单的方法来完成这一切,我愿意采取不同的步骤来实现相同的结果。)
最合适的回答,由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);
}