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

WordPress profile_update钩子无法获取更新后用户角色问题求助

问题:WordPress用户信息同步接口无法获取更新后的角色

背景代码

我编写了一段代码,用于在管理员或用户从后台修改用户信息时,将信息同步至指定接口:

// Función para enviar la actualización de perfil de usuario al endpoint
function send_profile_update_to_endpoint($user_id, $old_user_data = null, $userdata = null) {
    // Eliminar la entrada de caché correspondiente a los datos del usuario
    wp_cache_delete($user_id, 'users');

    // Obtener los datos del usuario modificado
    $user = get_userdata($user_id);

    $token = '-----------'; // Token de autorización

    // Verificar si el usuario tiene el rol "VIP" para establecer el valor de "partner"
    $partner = in_array('vip', (array) $user->roles);

    // Construir el array de datos del usuario para enviar en el body de la solicitud
    $user_data = array(
        'name' => $user->first_name,
        'surname' => $user->last_name,
        'email' => $user->user_email,
        'password' => base64_encode($user->user_pass),
        'passwordMD5' => $user->user_pass,
        'original_email' => $user->user_email,
        'username' => $user->user_login,
        'business_name' => '',
        'country' => '',
        'zip_code' => '',
        'phone' => '',
        'newsletter' => '',
        'partner' => $partner ? true : '',
        'member' => ''
    );

    $body = array('users' => array($user_data)); // Construir el cuerpo de la solicitud

    // Configurar los encabezados de la solicitud
    $headers = array(
        'Authorization' => 'Bearer ' . $token,
        'X-Requested-With' => 'XMLHttpRequest',
        'Content-Type' => 'application/json'
    );

    // Realizar la solicitud HTTP POST
    $response = wp_remote_post('https://test.com/api/users/sync', array(
        'method' => 'POST',
        'headers' => $headers,
        'body' => json_encode($body)
    ));

    // Verificar la respuesta de la solicitud
    if (is_wp_error($response)) {
        // Ocurrió un error al realizar la solicitud
        error_log('Error al enviar la actualización de perfil al endpoint: ' . $response->get_error_message());
    } else {
        $response_code = wp_remote_retrieve_response_code($response);
        $response_body = wp_remote_retrieve_body($response);

        // Verificar el código de respuesta y registrar el resultado en los registros
        if ($response_code === 200) {
            // La solicitud fue exitosa
            error_log('Actualización de perfil enviada al endpoint correctamente. Respuesta: ' . $response_body);
        } else {
            // La solicitud no tuvo éxito
            error_log('Error al enviar la actualización de perfil al endpoint. Código de respuesta: ' . $response_code);
        }
    }
}

当前问题

修改用户基础信息(如姓名)时接口能收到新数据,但修改用户角色时,钩子无法检测到更新后的角色,仍发送旧角色信息。例如将用户William的角色从super改为vip时,姓名更新为Alfred能被检测到,但角色仍为super。

推测原因

WordPress后台修改用户信息(含角色)时,profile_update钩子在wp_update_user正式更新角色前触发,导致代码获取旧角色。

已尝试的钩子(均无效)

  • 后台用户资料更新钩子:add_action('profile_update', 'send_profile_update_to_endpoint', 10, 3);
  • 角色变更钩子:add_action('set_user_role', 'send_profile_update_to_endpoint_roles', 10, 3);(已注释)
  • 前台个人资料更新钩子:add_action('personal_options_update', 'send_profile_update_to_endpoint', 10, 3);
  • WooCommerce账户更新钩子:add_action('woocommerce_update_customer', 'send_profile_update_to_endpoint', 10, 1);

额外问题

$userdata返回内容不含角色信息,与WordPress官方文档描述不符,返回内容如下:

(
[ID] => 289
[user_login] => pruebesita 23
[user_pass] => $P$BA8J63LF.1W5iH1gYPqhROT6s5Sb4y0
[user_nicename] => pruebesita-23
[user_email] => nose+34@gmail.com
[user_url] => 
[user_registered] => 2023-06-08 16:08:14
[user_activation_key] => 1686240496:$P$BfcKS1xXubceLVaE8fFjPXCVaMnJmO0
[user_status] => 0
[display_name] => manu eee
[first_name] => Manuel P
[last_name] => P M
[nickname] => vaale
[description] => 
[rich_editing] => true
[syntax_highlighting] => true
[comment_shortcuts] => 
[admin_color] => fresh
[use_ssl] => 0
[show_admin_bar_front] => true
[locale] => 
[facebook] => 
[instagram] => 
[linkedin] => 
[myspace] => 
[pinterest] => 
[soundcloud] => 
[tumblr] => 
[twitter] => 
[youtube] => 
[wikipedia] => 
)

需求

实现用户基础信息或角色变更时,均能将最新信息同步至指定接口。


解决方案

核心思路

WordPress中角色更新与用户基础信息更新的逻辑分离:profile_update触发时角色可能未完成写入,需通过提高钩子优先级确保数据完全更新,同时用set_user_role钩子单独处理角色变更场景。

优化后代码

// 调整优先级为99,确保用户数据(含角色)完全写入后触发
add_action('profile_update', 'send_profile_update_to_endpoint', 99, 3);
// 单独处理角色变更事件
add_action('set_user_role', 'send_profile_update_on_role_change', 10, 3);

function send_profile_update_to_endpoint($user_id, $old_user_data = null, $userdata = null) {
    // 强制清理用户主数据和元数据缓存,避免读取旧数据
    wp_cache_delete($user_id, 'users');
    wp_cache_delete($user_id, 'user_meta');

    $user = get_userdata($user_id);
    if (!$user) {
        error_log('无法获取用户ID: ' . $user_id . '的最新数据');
        return;
    }

    $token = '-----------'; // 替换为实际授权Token

    $partner = in_array('vip', (array) $user->roles);

    $user_data = array(
        'name' => $user->first_name,
        'surname' => $user->last_name,
        'email' => $user->user_email,
        'password' => base64_encode($user->user_pass),
        'passwordMD5' => $user->user_pass,
        'original_email' => $user->user_email,
        'username' => $user->user_login,
        'business_name' => '',
        'country' => '',
        'zip_code' => '',
        'phone' => '',
        'newsletter' => '',
        'partner' => $partner ? true : '',
        'member' => ''
    );

    $body = array('users' => array($user_data));

    $headers = array(
        'Authorization' => 'Bearer ' . $token,
        'X-Requested-With' => 'XMLHttpRequest',
        'Content-Type' => 'application/json'
    );

    $response = wp_remote_post('https://test.com/api/users/sync', array(
        'method' => 'POST',
        'headers' => $headers,
        'body' => json_encode($body)
    ));

    if (is_wp_error($response)) {
        error_log('同步用户信息失败: ' . $response->get_error_message());
    } else {
        $response_code = wp_remote_retrieve_response_code($response);
        $response_body = wp_remote_retrieve_body($response);
        if ($response_code === 200) {
            error_log('用户信息同步成功,响应: ' . $response_body);
        } else {
            error_log('用户信息同步失败,响应码: ' . $response_code . ', 响应内容: ' . $response_body);
        }
    }
}

// 角色变更时触发同步
function send_profile_update_on_role_change($user_id, $role, $old_roles) {
    send_profile_update_to_endpoint($user_id);
}

关键优化点

  1. 提高profile_update优先级:从默认10改为99,确保数据库中用户数据(包括角色)完全写入后再执行同步。
  2. 扩展缓存清理:除了users缓存,额外清理user_meta缓存,彻底避免读取旧角色数据。
  3. 单独处理角色变更:利用set_user_role钩子,角色变更时直接触发同步,覆盖纯角色修改的场景。
  4. 增加用户存在性检查:避免因用户数据未正确加载导致的同步错误。

补充说明

  • $userdata不含角色是正常现象:WordPress角色存储在用户元数据中,而非用户主表,官方文档描述存在模糊,通过get_userdata获取完整数据是正确方式。
  • WooCommerce场景可保留woocommerce_update_customer钩子,同样建议将优先级调整为99以确保数据更新完成。

内容的提问来源于stack exchange,提问作者Manuel Prieto macías

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 06:22:18