你确实有大量的帖子will 使用如此昂贵的操作使服务器崩溃(由于超过了最长执行时间)。我们需要以一种更聪明的方式来运行它。
首先,我们想得到所有的帖子,除了revision
和nav_menu_item
. 修订post_name
s是以不同的方式构建的,尝试用其他post类型处理它们也会使服务器崩溃
其次,我们需要在WP_Query
为了只获取帖子的ID、post\\u name、post\\u title、post\\u status、post\\u type和post\\u parent字段。这将大大减轻服务器的压力
第三,我们需要忽略更新所有术语和后期元缓存。这也给您的资源增加了额外的不必要的压力,所以我们需要排除更新它们,因为坦率地说,我们不需要post terms和meta
除了修订版以外的所有帖子类型,如果有这么多的帖子,您可能需要运行几次,但是如果您使用的代码有了巨大的改进,您可能只需要运行一次就可以了
您可以尝试以下操作:(您可以将其放入functions.php
或者用我的代码替换插件中的现有代码
add_action( \'wp\', function ()
{
global $wpdb;
add_filter( \'posts_fields\', function ( $fields, \\WP_Query $q ) use ( $wpdb )
{
remove_filter( current_filter(), __FUNCTION__ );
// Only target a query where the new custom_query parameter is set with a value of custom_meta_1
if ( \'custom_meta_1\' === $q->get( \'custom_query\' ) ) {
// Only get the ID, post_name, post_title, post_status, post_type and post_parent fields to reduce server load
$fields = "
$wpdb->posts.ID,
$wpdb->posts.post_title,
$wpdb->posts.post_name,
$wpdb->posts.post_type,
$wpdb->posts.post_status,
$wpdb->posts.post_parent
";
}
return $fields;
}, 10, 2);
// Get all public post types
$post_types = get_post_types( [\'public\' => true] );
$args = [
\'post_type\' => $post_types,
\'posts_per_page\' => -1,
\'suppress_filters\' => false, // Allow the posts_fields filter
\'custom_query\' => \'custom_meta_1\', // New parameter to allow that our filter only target this query
\'update_post_term_cache\' => false,
\'update_post_meta_cache\' => false
];
$q = get_posts( $args );
// Make sure we have posts before we continue, if not, bail
if ( $q ) {
// Loop through the posts
foreach ( $q as $single_post ) {
// Sanitize our post title
$new_slug = sanitize_title( $single_post->post_title );
// Check if our $new_slug is not equal to our post_name
if ( $single_post->post_name === $new_slug )
continue; // Do nothing further
// Our new slug and post name does not match, lets save a unique post_name
$post_name = wp_unique_post_slug(
$new_slug,
$single_post->ID,
$single_post->post_status,
$single_post->post_type,
$single_post->post_parent
);
// Last change to bail before we update the post_name field
if ( false !== stripos( $single_post->post_name, $post_name ) )
continue;
//Update the post_name field, wpdb::update is the quickest
$wpdb->update(
\'wp_posts\',
[\'post_name\' => $post_name], // string
[\'ID\' => $single_post->ID],
\'%s\',
\'%s\'
);
} // endforeach $q
}
}, PHP_INT_MAX );
编辑-修订如上所述,上述代码应用于所有职位,但作为修订的修订除外
post_name
是以不同的方式构建的。
以下代码将更新post_name
修订字段。你不应该把这段代码和上面的代码一起运行,它肯定会让你的服务器因为你的帖子数量而崩溃。您应该运行代码块1,删除它,然后运行代码块2,一旦完成就删除它,特别是代码块2,因为它非常昂贵。
代码如下:
add_action( \'wp\', function ()
{
global $wpdb;
add_filter( \'posts_fields\', function ( $fields, \\WP_Query $q ) use ( $wpdb )
{
remove_filter( current_filter(), __FUNCTION__ );
// Only target a query where the new custom_query parameter is set with a value of custom_meta_1
if ( \'custom_meta_1\' === $q->get( \'custom_query\' ) ) {
// Only get the ID, post_name, post_title, post_status, post_type and post_parent fields to reduce server load
$fields = "
$wpdb->posts.ID,
$wpdb->posts.post_title,
$wpdb->posts.post_name,
$wpdb->posts.post_type,
$wpdb->posts.post_status,
$wpdb->posts.post_parent
";
}
return $fields;
}, 10, 2);
$args = [
\'post_type\' => \'any\',
\'post_status\' => \'any\',
\'posts_per_page\' => -1,
\'custom_query\' => \'custom_meta_1\', // New parameter to allow that our filter only target this query
\'update_post_term_cache\' => false,
\'update_post_meta_cache\' => false
];
$q = get_posts( $args );
// Make sure we have posts before we continue, if not, bail
if ( $q ) {
// Now we can get the post revions and loop throught them
foreach ( $q as $single_post ) {
$rev_args = [
\'post_type\' => \'revision\',
\'post_status\' => \'inherit\',
\'post_parent\' => $single_post->ID,
\'posts_per_page\' => -1,
\'order\' => \'ASC\',
\'custom_query\' => \'custom_meta_1\', // New parameter to allow that our filter only target this query
\'update_post_term_cache\' => false,
\'update_post_meta_cache\' => false
];
$revisions = get_posts( $rev_args );
// Make sure we have revions before we continue
if ( $revisions ) {
// Loop through the revisions and set post_name
foreach ( $revisions as $key=>$revisions ) {
// Build a revision post slug in the format {$post->post_parent}-revision-v{$key + 1}
$post_name = $single_post->ID . \'-revision-v\' . ( $key + 1 );
// Make sure that we don\'t have a post_name yet with the name $post_name
if ( $revisions->post_name === $post_name )
continue; // Do nothing
//Update the post_name field, wpdb::update is the quickest
$wpdb->update(
\'wp_posts\',
[\'post_name\' => $post_name], // string
[\'ID\' => $revisions->ID],
\'%s\',
\'%s\'
);
}
}
}
}
}, PHP_INT_MAX );
编辑-在2015-07-08 23:23:45和2016-02-21 09:42:31之间如果您只需要针对两个特定日期之间的帖子和修订,您可以在查询参数中添加以下内容
$args
在两个代码块中
date_query
\'date_query\' => [
[
\'after\' => \'2015-07-08 23:23:45\',
\'before\' => \'2016-02-21 09:42:31\',
],
],
所以
$args = [
\'post_type\' => $post_types,
\'posts_per_page\' => -1,
\'suppress_filters\' => false, // Allow the posts_fields filter
\'custom_query\' => \'custom_meta_1\', // New parameter to allow that our filter only target this query
\'update_post_term_cache\' => false,
\'update_post_meta_cache\' => false
];
在块中,一变成
$args = [
\'post_type\' => $post_types,
\'posts_per_page\' => -1,
\'suppress_filters\' => false, // Allow the posts_fields filter
\'custom_query\' => \'custom_meta_1\', // New parameter to allow that our filter only target this query
\'update_post_term_cache\' => false,
\'update_post_meta_cache\' => false,
\'date_query\' => [
[
\'after\' => \'2015-07-08 23:23:45\',
\'before\' => \'2016-02-21 09:42:31\',
],
],
];