问题描述

我惊讶地发现,如果角色已经存在,那么 add_role() 会修改数据库并失败。这里有两个含义,首先比另一个更重要:1) 如果您正在开发和更新您的 add_role 代码,则必须先使用 remove_role() 2),否则您不应再次运行该代码。

所以通常我一直把我的 add_role() 放在 wp_loaded 动作钩子。而且,由于我正在开发中,我还在我的 add_role 之前添加了一个 remove_role(),所以我可以确定,如果我修改我的上限列表,它将会生效。

但是显然,这是每次访问博客页面时都会运行。好的,我可以把它放在一个 admin-only 动作中,或者我可以创建一个插件页面,可能在用户或工具下,可以创建一个这个角色。我想我希望有一个更简单,更优雅的解决方案。

我没想到有没有一个 run_once 的动作呢?

还是最好的做法只是添加角色,然后再使用 add_cap() 一次?即使如此,我想象,add_cap 正在访问数据库。

只是考虑减少不必要的数据库访问的最佳方式。你最好的做法是什么?

最佳解决方案

用户角色和功能被保存在数据库中,所以一旦你已经使用了 add_role()它的保存,然后下一次加载 WordPress 就会知道这个角色就像内置的角色一样。

现在,如果您更清楚地查看功能 add_role() at line 141,那么您将会看到,如果将 var $use_db 设置为 true(默认为默认值),则只能在数据库中保存角色和功能,以便在调用 add_role()功能和角色不会被保存。

尝试:

//globalize $wp_roles
global $wp_roles;
//set use_db to flase
$wp_roles->use_db = false;
//then add your role
$wp_roles->add_role( $role, $display_name, $capabilities );

更新:

如果它在测试/开发环境中,那么我看不出有什么缺点,但是如果你在一个现场环境中,那么你可以节省在每个负载上创建角色所需的时间。

对于最佳实践运行一次,如果在插件中,您应该使用 register_activation_hook,对于任何其他我使用简单的自定义条件函数:

function run_once($key){
    $test_case = get_option('run_once');
    if (isset($test_case[$key]) && $test_case[$key]){
        return false;
    }else{
        $test_case[$key] = true;
        update_option('run_once',$test_case);
        return true;
    }
}

**usage:**
if (run_once('add_user_role')){
    //do you stuff and it will only run once
}

参考文献

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