質問: wp_set_object_terms( 42, $cat_ids, 'category', true ); if ( is_wp_error( $term_taxonomy_ids ) ) { // there was an error somewhere and the terms couldn't be set. } else { // success! these categories were added to the post. }
回答: 私は、2500の投稿に対してカスタムsqlクエリを書く努力を正当化することを正当化しないでしょう。wp_set_object_terms( $object_id, ... )関数内には、次のものがあります。$object_id = (int) $object_id; そのため、入力として1つの投稿idのみを受け取ることが正しいです。それで、あなたはあなたの$post_ids配列をループする必要があるでしょう、しかしそれはwp_defer_term_counting()トリックを使うことで十分かもしれません1):/** * add terms to posts (with debug display) */ function wpse_terms_to_posts( $terms, $taxonomy, $append, &$post_ids ) { wp_defer_term_counting( true ); print '<ul>'; foreach( (array) $post_ids as $post_id ) { $tt_ids = wp_set_object_terms( $post_id, $terms, $taxonomy, $append ); print '<li>'; if( is_wp_error( $tt_ids ) ) printf( 'problem adding terms to post_id: %d - error: %s', $post_id, $tt_ids->get_error_message() ); else print 'success adding terms to post_id: ' . $post_id ; print '</li>'; } print '</ul>'; wp_defer_term_counting( false ); } ここでは、非常に大きい場合に備えて$post_idsを参照渡しします。用法(php 5.4以降):wpse_terms_to_posts( $terms = [ 6, 8 ], $taxonomy = 'category', $append = true, $post_ids = [ 123, 234, 345 ] ); 1回の実行で2500がシステムには多すぎる場合は、$post_ids配列をスライスすることもできます。以下は、そのような スライス 機能を付けてadmin-ajax.phpで関数を実行する方法の例です。私たちは自分自身の行動を次のように作り出します。/** * custom wp ajax action to activate our wpse_terms_to_posts() function * * example: /wp-admin/admin-ajax.php * ?action=wpse-terms-to-posts&wpse_offset=0&wpse_length=500 */ add_action( 'wp_ajax_wpse-terms-to-posts', function() { $offset = filter_input( input_get, 'wpse_offset', filter_sanitize_number_int ); $length = filter_input( input_get, 'wpse_length', filter_sanitize_number_int ); // check for user capability and non empty user input: if( current_user_can( 'manage_options' ) && '' !== $offset && '' !== $length ) { print '<h3>start:</h3>'; $start = microtime( true ); // settings - edit to your needs: $terms = [ 6, 8 ]; $taxonomy = 'category'; $append = true; $post_ids = [ 123, 234, 345, 456, 567, 678, 789 ]; // add terms to posts: wpse_terms_to_posts ( $terms, $taxonomy, $append, array_slice( $post_ids, $offset, $length ) ); printf( '<h3>done in %f seconds</h3>', microtime( true ) - $start ); exit(); } } ); post配列をスライスするためにwpse_offsetおよびwpse_length getパラメータを使用します。post ids配列を500のチャンクにスライスしたい場合は、次のように手動でアクティブにすることができます。/wp-admin/admin-ajax.php?action=wpse-terms-to-posts&wpse_offset=0&wpse_length=500 /wp-admin/admin-ajax.php?action=wpse-terms-to-posts&wpse_offset=500&wpse_length=500 /wp-admin/admin-ajax.php?action=wpse-terms-to-posts&wpse_offset=1000&wpse_length=500 /wp-admin/admin-ajax.php?action=wpse-terms-to-posts&wpse_offset=1500&wpse_length=500 /wp-admin/admin-ajax.php?action=wpse-terms-to-posts&wpse_offset=2000&wpse_length=500 そうすれば、用語の誤りをチェックすることができます。あなたがあなたのニーズに合わせてこれを修正できることを願っています。1) wp_defer_term_counting()は@janfabryのこの answer でwpseで最初に言及されました