wp_update_post中用变量设置post_parent无效问题排查及方案咨询
我做的应用允许用户提交表单创建文章(用Fieldmanager),表单里有个下拉框,用户可以选已发布的文章作为新文章的父页面。
我尝试用wp_update_post设置post_parent:先检查存储父文章标题的自定义字段,再用WP_Query查父文章ID,最后更新文章,代码如下:
$emergency_id = get_the_ID(); $parent = get_post_meta($emergency_id, 'Parent Call', true); if ($parent) { $parent_id = array( 'post_type' => 'hood_to_coast_calls', 'title' => $parent ); $parent_id_query = new WP_Query($parent_id); if ($parent_id_query->have_posts()) { while ($parent_id_query->have_posts()) { $parent_id_query->the_post(); $parent_hood_id = the_ID(); } } echo $parent_hood_id; $update_call = array( 'ID' => $emergency_id, 'post_type' => 'hood_to_coast_calls', 'post_parent' => $parent_hood_id ); wp_update_post($update_call); }
现在的问题是:$parent_hood_id输出显示的是正确ID,但放到wp_update_post里就没法设置父页面;换成具体数值就正常生效。
错误原因
你代码里的核心问题是用了the_ID()函数——这个函数的作用是直接输出当前文章的ID,而不是返回ID值。所以$parent_hood_id = the_ID()这行,其实是把输出的ID打印到页面上,而变量本身并没有被赋值(或者说赋值的是the_ID()的返回值,而这个函数返回的是null)。你看到的echo输出,其实是the_ID()执行时直接打印的,不是变量里的内容。
修正后的代码
把the_ID()换成get_the_ID(),这个函数会返回当前文章的ID,可以正常赋值给变量。另外,查询结束后记得调用wp_reset_postdata(),避免破坏全局的文章数据:
$emergency_id = get_the_ID(); $parent = get_post_meta($emergency_id, 'Parent Call', true); if ($parent) { $parent_query_args = array( 'post_type' => 'hood_to_coast_calls', 'title' => $parent, 'posts_per_page' => 1, // 只取第一条结果,避免标题重复的情况 'post_status' => 'publish' // 只查已发布的文章,和表单选项一致 ); $parent_id_query = new WP_Query($parent_query_args); $parent_hood_id = 0; // 初始化默认值 if ($parent_id_query->have_posts()) { while ($parent_id_query->have_posts()) { $parent_id_query->the_post(); $parent_hood_id = get_the_ID(); // 用get_the_ID()返回ID } wp_reset_postdata(); // 重置全局文章数据 } if ($parent_hood_id > 0) { // 确认获取到有效ID再更新 $update_call = array( 'ID' => $emergency_id, 'post_parent' => $parent_hood_id ); wp_update_post($update_call); } }
更优实现方案
其实没必要通过标题查ID,更高效的方式是在表单下拉框里直接存储父文章的ID,而不是标题:
配置Fieldmanager的下拉字段时,设置选项的
value为文章ID,显示文本为文章标题。比如用fm_select()的时候,生成选项数组时用文章ID作为键,标题作为值:$parent_options = array(); $parent_posts = get_posts(array( 'post_type' => 'hood_to_coast_calls', 'post_status' => 'publish', 'posts_per_page' => -1 )); foreach ($parent_posts as $p) { $parent_options[$p->ID] = $p->post_title; } $fm = new Fieldmanager_Select(array( 'name' => 'Parent Call', 'options' => $parent_options )); $fm->add_meta_box('Parent Call', 'hood_to_coast_calls');这样用户提交表单后,自定义字段
Parent Call存储的就是父文章的ID,直接拿来用就行,省掉WP_Query的步骤:$emergency_id = get_the_ID(); $parent_hood_id = get_post_meta($emergency_id, 'Parent Call', true); if ($parent_hood_id && is_numeric($parent_hood_id)) { $update_call = array( 'ID' => $emergency_id, 'post_parent' => $parent_hood_id ); wp_update_post($update_call); }
这种方式不仅效率更高,还能避免标题重复导致的查询错误(如果有两篇标题一样的文章,之前的代码会取最后一篇的ID,逻辑就错了)。
内容的提问来源于stack exchange,提问作者Cal Hart

