问题描述

我们编写和维护的一个 WP 插件有一个问题 – Export User Data

用户报告了 non-unique 用户元数据记录未正确返回的问题 – here

在插件中,我们导出由用户选择的 usermeta 数据 – 使用 get_users(),后者又使用 WP_User_Query:

我们通过几个简单的参数到 get_users:

// build argument array ##
$args = array(
      'fields'    => 'all',
      'role'      => sanitize_text_field( $_POST['role'] )
);

如果我们检查返回的 WP_User 对象,则不会返回 usermeta 字段 – 例如 (减少对象数据以节省空间):

Array
(
[0] => WP_User Object
    (
        [data] => stdClass Object
            (
                [ID] => 1267
                [user_login] => user@email.com
                ...
            )

        [ID] => 1267
        ...
    )

[1]...

我们已经尝试将 “所有” 中的 “fields” 参数的 get_users 参数改为 “all_with_meta”,但是这似乎并没有改变原来返回的数据。

在我们导出这些用户元数据行的时候,我们首先循环该 WP_User 对象数组,然后回显出个别的 usermeta 字段数据 ($字段来自 $ $循环外的 $字段的数组):

// build row values for each user ##
foreach ( $users as $user ) {

    // grab value from $user object ##
    $value = $user->{$field};

}

即使在原始返回的对象数据中未显示该字段数据,magically 被添加到 $ user 对象,但是我们无法控制是否为每个 usermeta 字段返回单个或数组的值。

当数据自动返回时,我们不会控制所选择的方法,如果我们直接使用 get_user_meta(但是我们仍然会遇到不知道存储的数据是否唯一的问题,而不需要额外运行) 查询 – 大量出口成本高昂) 。

我正在全力以赴尝试向他人解释这个问题,同时也帮助我们寻找答案并解决这个问题。

更新

我们已经使用一种检查 non-unique usermeta 键的方法将测试修复程序推送到 github,并返回一个阵列,以防止有多个匹配的键

最佳解决方案

我们结束的解决方案最终使用单个调用 get_user_meta 传递 $ user_id – 这样一来,所有用户数据都将在单个查询中返回,从而减少在大量用户数据导出期间 DB 上的重负载。

然后,我们对返回的数据进行一系列检查,包括:

  • is_serialized($ value) – 检查数据是否以序列化形式返回 (然后我们尝试将其取消排序 – 在某些情况下,如果数据以不正确的形式存储,则失败) 。

  • is_array($ value) – 检查返回的数据是否实际上是一个数组

如果我们发现数据在数组中返回,我们递归地展开数组,直到我们有一个数据字符串返回到导出文件。

我没有在这个答案中包含特定的代码,而是链接到托管的 github 文件 (我知道这不是未来的理想选择,但是与这个答案有关的部分在代码中展开) 。

出口运行干净,不要 choke-up – 我们将在下周发布更新的插件。

参考文献

注:本文内容整合自 Google/Baidu/Bing 辅助翻译的英文资料结果。如果您对结果不满意,可以加入我们改善翻译效果:薇晓朵技术论坛。