You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 21:17:00