如何在多站点(WPMU)安装中更改数据库前缀

时间:2013-09-05 作者:Mike Stumpf

我开始在客户的网站上实现安全功能,因此我想更改WP数据库前缀。然而,该网站是一个多站点安装(WPMU),因此要像您一样更改前缀normally 不起作用,我也不想manually change 每个子站点的wp配置文件(即,我不会监视子站点的创建)。

我也尝试在All-in-One WP安全插件上使用数据库前缀更改选项,但没有成功。

有人知道怎么做吗?如有任何想法,将不胜感激。

该网站正在运行WP 3.6

1 个回复
SO网友:Vinod Dalvi

只需调用以下函数,但请确保使用您要添加的任何表前缀更改新的\\u前缀,并检查配置文件路径是否正确。我使用find\\u wp\\u config\\u path()函数查找它,但有时它可能返回null。

function find_wp_config_path() {
    $dir = dirname(__FILE__);
    do {
        if( file_exists($dir."/wp-config.php") ) {
            return $dir;
        }
    } while( $dir = realpath("$dir/..") );
    return null;
}

function change_table_prefix() {

    global $wpdb, $table_prefix;
    $old_table_prefix = $table_prefix;
    $old_prefix_length = strlen( $old_table_prefix );
    $table_new_prefix = \'new_prefix\';

    /* Config file path */
    $path = find_wp_config_path();

    $error = $wpdb->set_prefix( $table_new_prefix );
    if ( is_wp_error( $error ) )
        wp_die( \'<strong style="color: #ff0000;">ERROR</strong>: table prefix can only contain numbers, letters, and underscores.\' );


    //Get the table resource
    $result = mysql_list_tables(DB_NAME);

    //Count the number of tables
    $num_rows = mysql_num_rows( $result );
    $table_count = 0;

    //Rename all the tables name
    for ($i = 0; $i < $num_rows; $i++) {

        //Get table name with old prefix
        $table_old_name = mysql_tablename($result, $i);

        if ( strpos( $table_old_name, $old_table_prefix ) === 0 ) {

            //Get table name with new prefix
            $table_new_name = $table_new_prefix . substr( $table_old_name, $old_prefix_length );

            //Write query to rename tables name
            // $sql = "RENAME TABLE $table_old_name TO $table_new_name";
            $sql = "RENAME TABLE %s TO %s";

            //Execute the query
            if ( false === $wpdb->query($wpdb->prepare($sql, $table_old_name, $table_new_name)) ) {
                $error = 1;
                echo "<p class=\'error\'>", $table_old_name, " table name not updated.</p>";
            } else {
                //echo "<p class=\'success\'>$table_old_name table name updated to $table_new_name.</p>";
                $table_count++;
            }
        } else {
            continue;
        }
    }
    if ( @$error == 1 ) {
        echo "<p class=\'error\'>Please change the above tables prefix to ", $table_new_prefix, " manualy.</p>";
    } else {
        echo "<p class=\'success\'>", $table_count, " tables prefix updated successfully.</p>";
    }

    //Update the wp-config.php file
    $configFile = file($path);
    foreach ($configFile as $line_num => $line) {
        switch (substr($line,0,16)) {
            case \'$table_prefix  =\':
                $configFile[$line_num] = str_replace($old_table_prefix, $table_new_prefix, $line);
                break;
        }
    }

    //making the the config readable to change the prefix
    @chmod($path, 0777);
    if ( is_writeable($path) ) {
        $handle = fopen($path, \'w\');
        foreach( $configFile as $line ) {
            fwrite($handle, $line);
        }
        fclose($handle);

        echo \'<p class="success">wp-config.php file updated successfully.</p>\';
    } else {
        echo "<p class=\'error\'>File Not Writeable: Please open wp-config.php file in your favurite editor and search 
              for variable", $table_prefix, " and assign ", $table_new_prefix, " to the same variable.";
    }

    //Create query to update option table
    $update_option_table_query = "UPDATE " . $table_new_prefix . "options 
                                  SET option_name=\'" . $table_new_prefix . "user_roles\' 
                                  WHERE option_name=\'" . $old_table_prefix . "user_roles\' 
                                  LIMIT 1";

    //Execute the update query to update option table user_roles row
    if ( false === $wpdb->query($update_option_table_query) ) {
        echo "<p class=\'error\'>Changing value: ",
             $old_table_prefix,
             "user_roles in table ",
             $table_new_prefix,
             "options to  ",
             $table_new_prefix,
             "user_roles</p>";

        echo "<p class=\'error\'>End of updating options table data with above error.</p>";
    } else {
        echo "<p class=\'success\'>Updated options table data successfully.</p>";
    }

    //Create query to update user_meta table
    $custom_sql = "SELECT user_id, meta_key 
                    FROM " . $table_new_prefix . "usermeta 
                    WHERE meta_key 
                    LIKE \'" . $old_table_prefix . "%\'";

    $meta_keys = $wpdb->get_results( $custom_sql );

    //Update all the meta_key field value which having the old table prefix in user_meta table
    foreach ($meta_keys as $meta_key ) {

        //Create new meta key
        $new_meta_key = $table_new_prefix . substr( $meta_key->meta_key, $old_prefix_length );

        $update_user_meta_sql = "UPDATE " . $table_new_prefix . "usermeta 
                                SET meta_key=\'" . $new_meta_key . "\' 
                                WHERE meta_key=\'" . $meta_key->meta_key . "\' 
                                AND user_id=" . $meta_key->user_id;

        $wpdb->query($update_user_meta_sql);

    }
    echo "<p class=\'success\'>Updated usermeta table data successfully.</p>";

}
或者你可以直接使用这个插件http://wordpress.org/plugins/change-table-prefix

结束

相关推荐

在许多外观相似的网站上使用MultiSite有什么缺点吗?

我正在为一位摄影师开发多个网站。大多数时候,我都会围绕摄影师拍摄的这些精彩图片进行定制设计,但在很多情况下,公司没有预算让我们创建定制设计的WP网站。因此,我正在寻找一种简单的方法,为我的客户提供一个“模板”。一个基本的网站,我设置,自定义一点,作为我们客户的服务。我的想法是:我创建了一个主题,每个新网站都有自己的子主题,只需稍作修改。所有网站在结构上都是相同的,但我会调整徽标、颜色、字体和总体外观。每个网站都有自己的域名,因此不涉及子域。它们都共享一些插件,比如GravityForms。这似乎是我的一个