我有一个与自定义帖子类型关联的元框。元框允许用户从下拉菜单中选择多个选项, 然后将其以序列化数组的形式保存到数据库中。如果用户仅选择一个选项, 则meta_value将存储为整数, 但是如果用户选择多个选项, 则将其以序列化数组的形式保存。
以下是显示和保存我的元框的功能
function av_add_meta_box() {$post_types = array( 'advertisements' );
foreach ( $post_types as $post_type ) {add_meta_box(
'avd_screen_meta_box', // Unique ID of meta box
'Set Screen', // Title of meta box
'av_display_meta_box', // Callback function
$post_type// Post type
);
}}
add_action( 'add_meta_boxes', 'av_add_meta_box' );
// display meta box
function av_display_meta_box( $post ) {$value = http://www.srcmini.com/get_post_meta( $post->
ID,'_av_meta_key', true );
if ( isset( $values['av-meta-box'] ) ) {
$value = http://www.srcmini.com/esc_attr( $values['ued-av-box'][0] );
}wp_nonce_field( basename( __FILE__ ), 'av_meta_box_nonce' );
//echo "<
pre>
";
print_r($value) ;
echo "<
/pre>
";
?>
<
select id="av-meta-box" type="text" name="av-meta-box[]" multiple="multiple">
<
option value="">
Select Screen<
/option>
<
?php $screens =json_decode(apply_filters("av_load_screens", "all"));
foreach ($screens as $screen) {
$location_name = json_decode(apply_filters("av_load_locations", $screen->
location));
$selected = "";
if(gettype($value) == "array"){
$selected = (in_array($screen->
id, $value))?"selected":"";
} else{
$selected = ($screen->
id == $value)?"selected":"";
}?>
<
option <
?php echo $selected;
?>
value="http://www.srcmini.com/<
?php echo $screen->
id;
?>">
<
?php echo $screen->
screen_name." - ".$location_name[0]->
location_name." (".$location_name[0]->
pin.") ";
?>
<
/option>
<
?php
} ?>
<
/select>
<
?php}// save meta box
function av_save_meta_box( $post_id ) {$is_autosave = wp_is_post_autosave( $post_id );
$is_revision = wp_is_post_revision( $post_id );
$is_valid_nonce = false;
if ( isset( $_POST[ 'av_meta_box_nonce' ] ) ) {if ( wp_verify_nonce( $_POST[ 'av_meta_box_nonce' ], basename( __FILE__ ) ) ) {$is_valid_nonce = true;
}}if ( $is_autosave || $is_revision || !$is_valid_nonce ) return;
if ( array_key_exists( 'av-meta-box', $_POST ) ) {update_post_meta(
$post_id, // Post ID
'_av_meta_key', // Meta key
array_map( 'strip_tags', $_POST[ 'av-meta-box' ])// Meta value
);
}}
add_action( 'save_post', 'av_save_meta_box' );
下面是我要传递给WP_Query的参数
$args = array(
'post_type' =>
'advertisements', 'meta_query' =>
array (
'key' =>
'_av_meta_key', 'value' =>
6, 'compare' =>
'IN'
)
);
【比较WP_Query中以序列化数组形式存储的meta_value】上面的WP_Query返回所有元值为6(整数)的帖子。但是, 如果meta_value存储在序列化数组中, 例如a:3:{i:0; s:1:” 6″ ; i:1; s:1:” 7″ ; i:2; s:1:” , 该怎么办? 8″ ; }
在我的情况下, post_id:20, meta_key:_av_meta_key和meta_value:a:3:{i:0; s:1:” 6″ ; i:1; s:1:” 7″ ; i:2; s: 1:” 8″ ; }
我希望我的WP_Query返回ID为20的帖子, meta_value是6或7或8。
#1我建议将(多个)值保存到数据库的多行中, 以避免从一开始就出现问题。 WordPress支持使用相同的键为自定义字段保存多个值。
你可以将保存价值的代码重写为:
if ( array_key_exists( 'av-meta-box', $_POST ) ) {
delete_post_meta( $post_id, '_av_meta_key' );
$values = array_map( 'absint', $_POST[ 'av-meta-box' ] );
foreach ( $values as $value ) {
add_post_meta( $post_id, '_av_meta_key', $value, false );
}
}
这样, 你可以编写查询而不必担心序列化数据。从数据库获取值很简单:
$values = get_post_meta( $post_id, '_av_meta_key', false );
PS:我建议使用自定义字段插件, 以避免编写重复的代码。正如我上面建议的那样, 它还可以帮助你解决此问题。
#2使用WP_Query和序列化数据很难获得正确的结果。你可以尝试使用LIKE关键字代替IN。
或者, 你可以使用自定义$ wpdb查询来获取所需的内容。
global $wpdb;
$posts = $wpdb->
get_results(
$wpdb->
prepare(
"
SELECT *
FROM $wpdb->
postmeta
LEFT JOIN $wpdb->
posts as post
ON post.id = post_id
WHERE post.post_type = %s
AND meta_key = %s
AND meta_value LIKE %s
", 'advertisements', '_av_meta_key', ':"6";
'
)
);
// Check if anything was found
if( $posts !== NULL ) {
foreach($posts as $post_info) {
// $post_info contains all post info as object
echo $post_info->
post_title;
}
}
你可以更改它所在的部分:” 6″ ; 达到你想要的价值。如果将数字包装在:” {number}” ; ” 中, 它将使搜索更好, 因为这是示例中序列化的方式, 这将使其更加精确匹配
更新:为每个屏幕ID设置元键
function av_add_meta_box() {$post_types = array( 'advertisements' );
foreach ( $post_types as $post_type ) {add_meta_box(
'avd_screen_meta_box', // Unique ID of meta box
'Set Screen', // Title of meta box
'av_display_meta_box', // Callback function
$post_type// Post type
);
}}
add_action( 'add_meta_boxes', 'av_add_meta_box' );
// display meta box
function av_display_meta_box( $post ) {$value = http://www.srcmini.com/get_post_meta( $post->
ID,'_av_meta_key', true );
if ( isset( $values['av-meta-box'] ) ) {
$value = http://www.srcmini.com/esc_attr( $values['ued-av-box'][0] );
}wp_nonce_field( basename( __FILE__ ), 'av_meta_box_nonce' );
//echo "<
pre>
";
print_r($value) ;
echo "<
/pre>
";
?>
<
select id="av-meta-box" type="text" name="av-meta-box[]" multiple="multiple">
<
option value="">
Select Screen<
/option>
<
?php $screens =json_decode(apply_filters("av_load_screens", "all"));
foreach ($screens as $screen) {
$location_name = json_decode(apply_filters("av_load_locations", $screen->
location));
$selected = "";
if(gettype($value) == "array"){
$selected = (in_array($screen->
id, $value))?"selected":"";
} else{
$selected = ($screen->
id == $value)?"selected":"";
}?>
<
option <
?php echo $selected;
?>
value="http://www.srcmini.com/<
?php echo $screen->
id;
?>">
<
?php echo $screen->
screen_name." - ".$location_name[0]->
location_name." (".$location_name[0]->
pin.") ";
?>
<
/option>
<
?php
} ?>
<
/select>
<
?php}// save meta box
function av_save_meta_box( $post_id ) {$is_autosave = wp_is_post_autosave( $post_id );
$is_revision = wp_is_post_revision( $post_id );
$screens= json_decode(apply_filters("av_load_screens", "all"));
$is_valid_nonce = false;
if ( isset( $_POST[ 'av_meta_box_nonce' ] ) ) {if ( wp_verify_nonce( $_POST[ 'av_meta_box_nonce' ], basename( __FILE__ ) ) ) {$is_valid_nonce = true;
}}if ( $is_autosave || $is_revision || !$is_valid_nonce ) return;
if ( array_key_exists( 'av-meta-box', $_POST ) ) {$selected_screens = array_map( 'absint', $_POST[ 'av-meta-box' ] );
foreach($screens as $screen) {
update_post_meta(
$post_id, '_av_meta_key_' . $screen->
id, in_array( $screen->
id, $selected_screens ) ? 'yes' : 'no'
);
}}}
add_action( 'save_post', 'av_save_meta_box' );
然后, 当你要使用WP_Query时, 可以构建一个数组以搜索所有键并将该关系设置为OR。
$meta_query = [
'relation' =>
'OR', ];
$screens= json_decode(apply_filters("av_load_screens", "all"));
foreach($screens as $screen) {
$meta_query[] = [
'key'=>
'_av_meta_key_' . $screen->
id, 'value'=>
'yes', 'compare'=>
'='
];
}$args = array(
'post_type'=>
'advertisements', 'meta_query' =>
$meta_query, );
推荐阅读
- 在WordPress中安装主题所需的连接信息
- 克隆具有自定义主题的WordPress Woo Commerce网站
- 更改WooCommerce可用性文本并包括原始HTML
- 基于类别的分类网站结构
- linux下curl访问金蝶接口
- 智汀云盘-功能概述
- ccat – 使用语法突出显示输出内容
- 终于把性能测试这事儿讲清楚了
- keepalived的weight