WordPress中update_field()无法更新ACF单选按钮问题求助
WordPress批量图片检测后ACF字段更新异常问题
我正在开发一个类方法,用于批量处理WordPress站点中virtual_run类型文章内的图片(每次处理10张)。通过Clarifai API检测图片是否有人物,然后修改Advanced Custom Fields(ACF)的两个单选按钮:标记图片是否已检测,以及是否含有人物。
图片检测功能正常,但使用update_field()函数修改自定义字段时,无法更新对应检测图片的单选按钮,甚至会错误更新未提交检测的图片。之前单张图片检测时update_field()能正常工作,改成批量检测后出现该问题。我已经用echo验证执行流程,var_dump()检查Clarifai返回结果,均显示正常。
相关代码
FaceDetection类代码
class FaceDetection { public function getErgebnisImageArray() { $ergebnisImageArray = array(); $field_id = 0; $triumveret = 0; $rd_query = new WP_Query(array( 'post_type' => 'virtual_run', 'post_status' => array('publish', 'pending', 'draft', 'auto-draft'), )); if($rd_query->have_posts()){ while ($rd_query->have_posts()) { // loop the posts $rd_query->the_post(); if(have_rows('ergebnis')) { while(have_rows('ergebnis')) { // loop the ergebnis the_row(); if( have_rows('beweis') ){ while(have_rows('beweis')) { // While there are rows that have the beweis field the_row(); if(get_sub_field('checked') == 'no'){ // if the sub field has not been checked before ... if(count($ergebnisImageArray) < 10){ // if the array has less than 10 entries echo "getsrunonce "; $image_url = get_sub_field('url'); // get the value from the sub field url $fullpath = get_template_directory_uri() . '/' . $image_url; // make the full path $field = get_field_object('checked'); // get value from the checked field $human_field = get_sub_field_object('mensch'); // get the value from the human field $field['ID'] = $field_id; $human_field['ID'] = $field_id + 1; // always up the value from the human field by one $idOfField = $field['ID']; $idOfHumanField = $human_field['ID']; $ergebnisImageArray[$triumveret] = array('image_url'=> $fullpath, 'field_id'=> $idOfField, 'field_id_human'=> $idOfHumanField); // insert array with url and the two field id's $triumveret++; // increase the value so that the next entry can be added $field_id+=2; // so that the ids go up each run } if(count($ergebnisImageArray) == 10){ // If there are 10 entrys in the $ergebnisImageArray send them to clarifai $detection = new clarifaiAccess; // new class instance $api = $detection->clarifai($ergebnisImageArray); // give array to class method $data = $api; // returnes an array with the resultt foreach($data as $arrayitem){ // foreach array in the returned array $resultDetection = $arrayitem['value']; // get the value if it was a human or not (true/false) $fid = $arrayitem['fieldId']; // get the id of the first field $hfid = $arrayitem['humanfieldId']; // get the ai of the second fields if($resultDetection == true){ // If clarifai returns Binary-Positive the array gets the value of true update_field("checked", "yes", $fid); // Update the checked field in the backend update_field("mensch", "yes", $hfid); // Update the human field in the backend echo " True(" . $fid . " " . $hfid . ") "; }elseif ($resultDetection == false){ // If clarifai returns Binary-Negative the array gets the value of false update_field("checked", "yes", $fid); // Update the checked field in the backend update_field("mensch", "no", $hfid ); // Update the human field in the backend echo " False(" . $fid . " " . $hfid . ")"; } } $ergebnisImageArray = array(); // clear the array $triumveret = 0; // reset the array input placement } } else{ echo "It was already checked; "; } } } } } } } } }
clarifaiAccess类代码
class clarifaiAccess { function clarifai($ergebnisImageArray){ $c = 0; $justimages = array(); foreach (array_column($ergebnisImageArray, 'image_url') as $value) { // take all images and put them in an array $justimages[] = $value; } $index = 0; foreach ($justimages as $image) { $newinputs[] = array( // THIS IS HOW TO SEND MULTIPLE IMAGES!!!!!!!! "data" => array( "image" => array( "url" => $image, "allow_duplicate_url" => true ) ), "id" => "image" . ($index++) ); } $headers = array( 'Authorization: ' . KEY, 'Content-Type: application/json', ); $data = array( 'user_app_id' => array( 'user_id' => USERID, 'app_id' => APPID, ), 'inputs' => $newinputs, ); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, URLURL); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data)); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($ch); $responseArray = json_decode($response, true); $resultarray = array(); foreach ($responseArray['outputs'] as $output) { $regions = $output['data']['regions']; $human_detected = false; foreach ($regions as $region) { $concepts = $region['data']['concepts']; foreach ($concepts as $concept) { if ($concept['name'] == 'BINARY_POSITIVE') { $human_detected = true; } elseif($concept['name'] == 'BINARY_NEGATIVE'){ $human_detected = false; } } } $resultarray[] = array('value' => $human_detected, 'fieldId' => $ergebnisImageArray[$c]['field_id'], 'humanfieldId' => $ergebnisImageArray[$c]['field_id_human']); var_dump($resultarray); $c++; } curl_close($ch); return $resultarray; } }
问题根源与修复方案
核心问题
你手动生成$field_id来设置ACF字段ID的逻辑完全错误。ACF嵌套repeater字段的真实ID是和文章ID、行索引绑定的唯一标识,不是连续递增的数字。批量处理时,手动ID和真实字段ID完全脱节,导致update_field()更新错误的字段;单张处理时可能凑巧ID重合,才暂时正常。
修复代码
修改FaceDetection类
去掉手动生成ID的逻辑,改用ACF字段的键路径+文章ID来更新:
class FaceDetection { public function getErgebnisImageArray() { $ergebnisImageArray = array(); $batchSize = 10; $rd_query = new WP_Query(array( 'post_type' => 'virtual_run', 'post_status' => array('publish', 'pending', 'draft', 'auto-draft'), )); if($rd_query->have_posts()){ while ($rd_query->have_posts()) { $rd_query->the_post(); $post_id = get_the_ID(); if(have_rows('ergebnis', $post_id)) { while(have_rows('ergebnis', $post_id)) { the_row(); $ergebnis_row = get_row_index(); if( have_rows('beweis', $post_id) ){ while(have_rows('beweis', $post_id)) { the_row(); $beweis_row = get_row_index(); if(get_sub_field('checked') == 'no'){ if(count($ergebnisImageArray) < $batchSize){ echo "getsrunonce "; $image_url = get_sub_field('url'); $fullpath = get_template_directory_uri() . '/' . $image_url; // 存储更新所需的关键信息 $ergebnisImageArray[] = array( 'image_url' => $fullpath, 'post_id' => $post_id, 'checked_key' => "ergebnis_{$ergebnis_row}_beweis_{$beweis_row}_checked", 'mensch_key' => "ergebnis_{$ergebnis_row}_beweis_{$beweis_row}_mensch" ); } if(count($ergebnisImageArray) == $batchSize){ $detection = new clarifaiAccess; $api_results = $detection->clarifai($ergebnisImageArray); foreach($api_results as $index => $item){ $result = $item['value']; $target_post = $ergebnisImageArray[$index]['post_id']; $checked_key = $ergebnisImageArray[$index]['checked_key']; $mensch_key = $ergebnisImageArray[$index]['mensch_key']; update_field($checked_key, "yes", $target_post); update_field($mensch_key, $result ? "yes" : "no", $target_post); echo $result ? " True(" . $target_post . ") " : " False(" . $target_post . ")"; } $ergebnisImageArray = array(); } } else{ echo "It was already checked; "; } } } } } } wp_reset_postdata(); } } }
调整clarifaiAccess类
仅返回检测结果,无需传递错误的字段ID:
class clarifaiAccess { function clarifai($ergebnisImageArray){ $justimages = array_column($ergebnisImageArray, 'image_url'); $newinputs = array(); $index = 0; foreach ($justimages as $image) { $newinputs[] = array( "data" => array( "image" => array( "url" => $image, "allow_duplicate_url" => true ) ), "id" => "image" . ($index++) ); } $headers = array( 'Authorization: ' . KEY, 'Content-Type: application/json', ); $data = array( 'user_app_id' => array( 'user_id' => USERID, 'app_id' => APPID, ), 'inputs' => $newinputs, ); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, URLURL); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data)); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($ch); $responseArray = json_decode($response, true); $resultarray = array(); foreach ($responseArray['outputs'] as $output) { $human_detected = false; if(!empty($output['data']['regions'])){ foreach ($output['data']['regions'] as $region) { foreach ($region['data']['concepts'] as $concept) { if ($concept['name'] == 'BINARY_POSITIVE') { $human_detected = true; } elseif($concept['name'] == 'BINARY_NEGATIVE'){ $human_detected = false; } } } } $resultarray[] = array('value' => $human_detected); } curl_close($ch); return $resultarray; } }
额外优化
- 添加
wp_reset_postdata()重置查询,避免全局变量污染 - 用
$batchSize常量替代硬编码的10,方便后续修改 - 增加空数组判断,避免循环报错
内容的提问来源于stack exchange,提问作者OnyxCoding
相关产品推荐
相关产品推荐

