阻止在WordPress更新上更改POST_NAME列的长度

时间:2020-08-12 作者:Jafar Abazeed

我们有一些阿拉伯语网站在WordPress上运行,并且在帖子的URL中使用阿拉伯语slug。

你知道post slug存储在post_name 中的列wp_posts 表,此列的默认长度为200 字符,这对于存储在此列之前正在编码的阿拉伯语段塞来说是不够的。为此,我们将此列的长度更改为1000 字符来保存我们拥有的长编码段塞。

问题是,当我们将WordPress代码更新为主要更新时,它会将此列修剪回200 字符,这会打断帖子的URL。如果您在更新CMS后首次登录或执行Network Upgrade 每次主要更新后都会提示。

有什么方法可以防止WordPress接触到表的结构吗?

更新在网络升级后,我试图运行SQL查询来更改post_name 列,但我遇到了一个SQL语法错误,而在使用DB控制台运行同一查询时,我没有遇到任何问题。

这是我的代码:

function after_network_upgrade() {
    global $wpdb;
    // Get the length of the `post_name` column in the `posts` table.
    $query = $wpdb->prepare(  "
        SELECT CHARACTER_MAXIMUM_LENGTH
        FROM INFORMATION_SCHEMA.COLUMNS
        WHERE 
            TABLE_NAME   = \'%s\' AND 
            COLUMN_NAME  = \'post_name\'
        ", $wpdb->base_prefix.\'posts\' );
    $post_name_max_length = $wpdb->get_results($query)[0]->CHARACTER_MAXIMUM_LENGTH;
    // if the length is set to the default value `200`, then do the fix.
    if ($post_name_max_length == 200) {
        $wpdb->query("
            ALTER TABLE wp_posts   MODIFY `post_name` VARCHAR(1000) NULL;
            ALTER TABLE wp_2_posts MODIFY `post_name` VARCHAR(1000) NULL;
            ALTER TABLE wp_3_posts MODIFY `post_name` VARCHAR(1000) NULL;
            ALTER TABLE wp_4_posts MODIFY `post_name` VARCHAR(1000) NULL;
            ALTER TABLE wp_terms   MODIFY `slug`      VARCHAR(500)  NULL;
            ALTER TABLE wp_2_terms MODIFY `slug`      VARCHAR(500)  NULL;
            ALTER TABLE wp_3_terms MODIFY `slug`      VARCHAR(500)  NULL;
            ALTER TABLE wp_4_terms MODIFY `slug`      VARCHAR(500)  NULL;
            UPDATE wp_posts   SET `post_name` = `post_name_copy`;
            UPDATE wp_2_posts SET `post_name` = `post_name_copy`;
            UPDATE wp_3_posts SET `post_name` = `post_name_copy`;
            UPDATE wp_4_posts SET `post_name` = `post_name_copy`;
            UPDATE wp_terms   SET `slug`      = `slug_copy`;
            UPDATE wp_2_terms SET `slug`      = `slug_copy`;
            UPDATE wp_3_terms SET `slug`      = `slug_copy`;
            UPDATE wp_4_terms SET `slug`      = `slug_copy`;"
        );
        if ($wpdb->last_error !== \'\') {
            print "<p class=\'wpdberror\'><strong>WordPress database error:</strong><code>";
            print_r ($wpdb->last_error);
            print "</code><br /></div>";
        } else {
            print "<div>The length of the `post_name` column length is FIXED!</div>";
        }
    }
}
add_action( \'after_mu_upgrade\', \'after_network_upgrade\', 10, 1 );
这个post_name_copyslug_copy 是保存post_nameslug 发生问题时要使用的值。

这是我得到的打印SQL错误:

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near \'ALTER TABLE wp_2_posts MODIFY post_name VARCHAR(1000) NULL; ALTER \' at line 2

有什么需要帮忙的吗?

1 个回复
SO网友:mozboz

我没有明确的答案,但我快速查看了一些升级代码,注意到一个非常旧的升级函数使用sanitize_title 函数,并调用sanitize_title_with_dashes, 其中包含以下代码:

  if ( seems_utf8( $title ) ) {
    if ( function_exists( \'mb_strtolower\' ) ) {
      $title = mb_strtolower( $title, \'UTF-8\' );
    }
    $title = utf8_uri_encode( $title, 200 );
  }
请注意,这非常有趣,因为如果函数mb_strtolower 此代码是否会导致字符串被截断为200个字符!

您可以快速检查您的系统,看看是否安装了PHP多字节字符串扩展,因为如果没有安装,清理标题将截断标题,等等maybe 您可以通过安装PHP多字节扩展来解决问题。

要检查是否是这种情况,请查看phpinfo();, 或者直接在服务器上的某个位置运行此命令:

if ( function_exists( \'mb_strtolower\' ) ) {
   echo "yes mb strings installed";
} else {
   echo "no mb strings not installed";
}
Please note: 有太多的代码让我无法验证您的案例中是否确实发生了这种情况。其他人可能有明确的答案。“200”值与您的实际情况完全一致,这似乎是一个很好的迹象,表明这可能是一个问题,但我没有找到任何具体的地方在每次升级时都会调用它。

相关推荐

Product-attribute-slug-is-too-long-28-characters-max

谷歌没有解决我的问题,所以。。这里的任何人都知道如何增加woocommerce产品属性slug的字符限制,默认情况下它的字符限制为28个(数据库中最多32个),我需要最多40个。(试图增加到最大128)。我正在测试一个本地站点,其中产品信息来自导入的xml文件,有时某些属性名称的长度刚刚超过28个字符。。将数据库中的相应列从vachar(32)更改为varchar(128),试图更改中的值wc-attribute-functions.php, 将28改为128,但这没有帮助。。// Validate sl