【问题标题】:Override WP_SITEURL and WP_HOME for WordPress Multisite为 WordPress 多站点覆盖 WP_SITEURL 和 WP_HOME
【发布时间】:2012-10-18 15:23:29
【问题描述】:

为了在 WordPress 网站 (http://www.example.com) 上进行本地开发,我之前在 wp-config.php 中覆盖了 WP_SITEURLWP_HOME 值,如下所示:

define('WP_SITEURL', 'http://local-example/');
define('WP_HOME', 'http://local-example/');

这将允许我将数据库和站点文件复制到本地服务器,并根据需要进行修改,在本地安装上进行测试。

然后有必要将安装转换为 WordPress 多站点,以便用户、身份验证、插件等可以在主站点和辅助站点之间共享,托管在子域 (http://second.example.com) 上。

上面覆盖wp_options 表中的值的方法不再有效,但我不确定为wp_blogswp_2_options 表中的条目设置值的正确方法主要和子域。

更新我的HOSTS 文件在某种程度上是一种解决方法,但并不理想(我无法与实时站点等进行比较)。运行脚本来更改数据库值是我尝试过的另一个选项,但稍微麻烦一些,所以我的问题是 MultiSite 中是否有选项可以覆盖设置文件中的这些值,例如wp-config.php,以及如果是这样,它会是什么样子。

【问题讨论】:

    标签: configuration development-environment wordpress


    【解决方案1】:


    更新: 完整更新的插件代码和附加说明可以在这里找到:http://justinsilver.com/technology/wordpress/wordpress-plugins/wordpress-plugin-wp-server-migration/
    在@user916011 的帮助下,我想出了一个解决方案。我需要能够将wp_options 表复制到我的开发环境中,因为它们包含所需的配置。为了克服无法在 MultiSite 中设置 WP_SITEURL 和 WP_HOME 值的问题,我编写了一个自定义过滤器来替换可用于非多站点安装的 _config_wp_siteurl()_config_wp_home() 函数,这些函数包含在一个插件中在网络范围内可用,并在wp-config.php 中配置。然后,我可以将所有数据库表 except wp_sitewp_blogs 复制到本地数据库。

    我强烈推荐 Chris Murphy 的 URL Token Replacement Techniques for WordPress 3.0 文章来帮助处理您内容中的 URL。

    本示例假定子域多站点安装,域为example.com 和两个子域www.example.comsecond.example.com。本地开发 URL 将分别为 www.example.localsecond.example.local

    数据库更改

    更新wp_site中的域值:

    UPDATE wp_site SET domain = 'example.local' WHERE domain = 'example.com';
    

    更新wp_blogs 中的域值:

    UPDATE wp_blogs SET domain = 'www.example.local' WHERE domain = 'www.example.com';
    UPDATE wp_blogs SET domain = 'second.example.local' WHERE domain = 'second.example.com';
    

    插件代码: 以下插件应安装在网络范围内。

    <?php
    /*
    Plugin Name: MultiSite WP_HOME and WP_SITEURL
    Plugin URI: http://doublesharp.com/
    Description: Allows wp_options values to be overwritten in wp-config.php for MultiSite
    Author: Justin Silver
    Version: 1.0
    Author URI: http://doublesharp.com
    License: GPL2
    */
    
    function _ms_config_wp_siteurl( $url = '' ) {
        if (is_multisite()):
            global $blog_id, $current_site;
            $cur_blog_id = defined('BLOG_ID_CURRENT_SITE')? BLOG_ID_CURRENT_SITE : 1;
            $key = ($blog_id!=$cur_blog_id)? $blog_id.'_' : '';
            $constant = 'WP_'.$key.'SITEURL';
            if ( defined( $constant ) )
                return untrailingslashit( constant($constant) );
        endif;
        return $url;
    }
    add_filter( 'option_siteurl', '_ms_config_wp_siteurl' );
    
    function _ms_config_wp_home( $url = '' ) {
        if (is_multisite()):
            global $blog_id;
            $cur_blog_id = defined('BLOG_ID_CURRENT_SITE')? BLOG_ID_CURRENT_SITE : 1;
            $key = ($blog_id!=$cur_blog_id)? $blog_id.'_' : '';
            $constant = 'WP_'.$key.'HOME';
            if ( defined( $constant ) )
                return untrailingslashit( constant($constant) );
        endif;
        return $url;
    }
    add_filter( 'option_home',    '_ms_config_wp_home'    );
    ?>
    

    配置 wp-config.php

    wp-config.php 添加新常量。主站点应使用标准的WP_HOMEWP_SITEURL,第三级URL 应使用WP_{$blog_id}_HOMEWP_{$blog_id}_SITEURL

    define('WP_HOME',      'http://www.example.local');
    define('WP_SITEURL',   'http://www.example.local');
    define('WP_2_HOME',    'http://secondary.example.local');
    define('WP_2_SITEURL', 'http://secondary.example.local');
    

    【讨论】:

    • 这是完美的。非常感谢。
    • 没问题,我最终扩展了它以做更多的事情,包括在此处替换内容中的链接:justin.ag/technology/wordpress-plugins/… 元挂钩被注释掉,因为我遇到了一些问题(这可能是与缓存有关)但我已经在我的一个多站点上使用它一段时间了,没有任何问题。您需要定义一个WP_DEVELOPMENT=true 常量来进行 URL 重写,url 令牌替换应该一直运行。
    • 在尝试了插件和一切之后,最后一个定义救了我……但我还必须重新访问网络 wordpress 管理页面并重新保存每个站点页面。
    • WP_HOME 和 WP_SITEURL 在 MS 中应该没有任何影响
    • @ar099968 这是正确的,也是我遇到的确切问题。在迁移到 MultiSite 之前,我一直在利用它们,并且需要一种方法来实现相同的功能,而我编写的插件在很大程度上就是这样做的。
    【解决方案2】:

    你可以在functions.php中使用update_option

    update_option("siteurl","http://example.com");
    update_option("home","http://example.com");
    

    【讨论】:

    • 这个解决方案的问题是,当我在本地运行站点时,它的 URL 是 http://local-example/ 与主站点的数据库值 http://www.example.com 不匹配。因此,functions.php 中的任何代码都不会执行,因此不会更新选项。鸡和鸡蛋。
    【解决方案3】:

    这里有一个类似的问题:Team Development of a Wordpress Site 我提供了一个可能的解决方案。在您的情况下,您可能不想达到那种程度(尽管它会非常灵活);但是,您始终可以查看提到域替换技术的答案部分。

    我在此处概述了该解决方案:URL Token Replacement Techniques...

    【讨论】:

    • 很好,实际上有很多很棒的信息,尤其是 URL 令牌替换。不幸的是,它对我的​​情况并没有完全帮助,因为我需要覆盖实际的数据库值(从我可以看出wp-includes/ms-settings.php.
    • 基本上,您属于我在另一篇文章中概述的解决方案的案例 2。这是一个与 WP 一致的问题(尽管不是 WP 本身所特有的),不幸的是,这个问题没有简单的解决方案——除非你想做一些代理魔法或在.htaccess 文件中创建一些非常复杂的路由规则。我对 WP MU/Multi-site 的经验是,您需要在开始之前预先配置您的环境(使用我概述的方法)。否则,需要大量 SQL 查询来替换数据库中的值。
    • 技术上在案例 2 中,但该站点未上线,因此我可以做任何我需要的设置。问题不在于内容本身的 URL,而是wp_options['siteurl'](主站点)、wp_site['domain'](多站点)、wp_blogs['domain'](主、第二博客)和wp_2_options['siteurl'](辅助站点)中保存的 URL )。以前我只需要担心wp_options['siteurl'] 并且可以在wp-config.php 中覆盖它,但是我看不到如何在每次复制数据库时不更新这些表值的情况下执行此操作。暂时忽略内容 URL。
    • 我实际上可能刚刚想到了一个解决方案,使用您的方法和我编写的一些代码来覆盖 wp_optionswp_2_options 中的值 - 如果我设置自定义 wp_site 的开发版本和wp_blogs 的值从生产中更改,而不是复制这些用于开发工作。然后我应该能够使用自定义 wp-config.php 值(我的实现与您的略有不同,但原理相同)。我遇到的问题是ms-settings.php 文件有一些硬编码查询来查找 blog_id 等。
    • 查看该帖子的最后一部分关于同步的内容。问题是:如果您有一个与暂存环境分开的开发环境,则不需要转储每个表,例如wp_options。您只需要转储相关的内容表,这样您就不会必须更改开发沙箱中的值。所以,这里应该发生的是内容提升从登台到生产的上游,而镜像从登台到沙箱的下游发生。这样每个环境只需要配置一次,只剩下要推广的内容。
    【解决方案4】:

    我遇到了同样的问题,想要一个类似于在 wp-config.php 中定义 WP_HOME 和 WP_SITEURL 的解决方案。

    我不能使用插件,因为我正在与 GIT 同步,并且不想在我的仓库中使用该插件,而且我每次都必须添加插件......我想它可以通过网络在网络范围内激活wp_sitemeta 表...但对我来说并不理想。

    我想出了这个解决方案。

    确保不要同步 wp_blogs、wp_site、wp_sitemeta。然后将此代码添加到您本地的 wp-config.php $table_prefix 下方某处:

    /* Update local database */
    mysql_connect( DB_HOST, DB_USER, DB_PASSWORD ) or die( mysql_error() );
    mysql_select_db( DB_NAME );
    
    $result = mysql_query("SELECT * FROM `". $table_prefix ."blogs`") or die( mysql_error() );
    while( $row = mysql_fetch_array( $result ) )
    {
        $id = (1 == $row['blog_id']) ? '' : $row['blog_id'] .'_';
        mysql_query( "UPDATE `". $table_prefix . $id ."options` SET `option_value`='http://". $row['domain'] ."/' WHERE (`option_name`='siteurl' OR `option_name`='home')" ) or die( mysql_error() );
    }
    

    这将确保您的网站同步到您的本地 wp_blogs 表。

    唯一的缺点是当您添加一个新站点时,您确实需要手动将其复制到您的 wp_blogs 表中并更新其本地 url。

    【讨论】:

    • 我不敢相信我没想过那样做。这将在每次页面加载时运行更新 - 您可以使用选项表中的值来确定是否需要运行更新以防止这种情况发生,即使它不会对性能造成太大影响。即使 WordPress 仍在使用 mysql_* 扩展,PDO 或 mysqli 也可以很好地进行未来验证。
    • 如果您希望能够刷新整个数据库,另一种选择是将 blog_id => url 映射存储在 wp_config.php 的数组中并更新 blogssites、和options 使用它的表。
    • 肯定有选择。这真的很简单。数组也可能是一个不错的选择。我开始这样做,但决定不这样做。我现在不知道为什么...也许是因为 blogs 表中已经包含站点 ID...它在每次页面加载时都在运行,但是由于我只在本地使用它,所以我不在乎。我会针对现场环境对其进行改进,并且在不使用它时倾向于将其注释掉。而且它不像插件那么强大。显然内容中的链接仍然保持不变,但我只是想要一些简单和便携的东西。
    【解决方案5】:

    这个问题太老了,无法回答,但最近我遇到了类似的情况,我必须将我的 wp 站点从暂存迁移到生产,这很痛苦,因为它有 5 个子站点。

    在摸索了一整天后,我找到了一个简单而有用的解决方案。

    当然必须在 wp-config.php 中进行更改。

    除此之外,您必须按照以下步骤操作。

    使用以下命令生成数据库转储。

    mysqldump -u [user name] –p [password] [options] [database_name] [tablename] > [FileName]
    

    然后在任何编辑器中打开该文件。

    查找并用新域替换旧域。

    现在使用您创建的转储恢复数据库。

    mysql -u [user name] -p [password] [database name] < [file anme]
    

    【讨论】:

    • 不幸的是,这不会非常可靠地工作 - 如果元字段的任何选项包含带有 URL 的序列化值,那么如果域的长度不同,那么仅更新就会破坏数组等。
    • @doublesharp,它可能,但在我的情况下它工作得很好,而且如果有多个站点,一个人可以把硬币扔到这个解决方案中,几乎不需要 5 分钟。在确保你有 sqldump 备份之前。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-05-03
    • 1970-01-01
    • 2020-12-03
    • 1970-01-01
    • 2014-12-04
    • 1970-01-01
    • 2013-04-20
    相关资源
    最近更新 更多