save_post フックの使い方|説明・引数・注意点

説明

save_post は、投稿が保存(作成・更新)されたときに実行されるアクションです。カスタムフィールドの保存などに使います。

基本構文

do_action( 'save_post', int $post_id, WP_Post $post, bool $update )

引数

  • $post_id:投稿ID
  • $post:WP_Post オブジェクト
  • $update:更新なら true、新規なら false

戻り値

値は返しません。

使い方(サンプル)

add_action( 'save_post', function( $post_id ) {
	if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
		return;
	}
	if ( ! current_user_can( 'edit_post', $post_id ) ) {
		return;
	}
	update_post_meta( $post_id, 'my_key', 'value' );
} );

注意点

  • 自動保存・リビジョンでも呼ばれるため、DOING_AUTOSAVE や wp_is_post_revision() で除外します。
  • nonce検証と権限チェックを必ず行います。
  • フック内で wp_update_post() を呼ぶと無限ループになります。

実務での使いどころ

  • メタボックスで入力したカスタムフィールドの値を、保存するとき。
  • 投稿の保存をきっかけに、キャッシュの削除や通知を行うとき。
  • 特定の投稿タイプの保存時だけ、処理を行うとき(save_post_{post_type})。

よくあるミスと対処

  • 自動保存(DOING_AUTOSAVE)やリビジョンでも実行され、処理が何度も走る。
  • nonceと権限(current_user_can( 'edit_post', $post_id ))の確認をしていない。
  • フックの中で wp_update_post() を呼び、無限ループになる。呼ぶ前にフックを外し、呼んだ後に付け直します。
  • すべての投稿タイプで実行される。特定の投稿タイプだけに絞りたいときは、save_post_{post_type} を使います。

NG例

add_action( 'save_post', function ( $post_id ) {
	wp_update_post( array( 'ID' => $post_id, 'post_title' => '更新' ) ); // 無限ループになる
} );

OK例

add_action( 'save_post', 'my_save_post' );
function my_save_post( $post_id ) {
	if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
		return;
	}
	if ( wp_is_post_revision( $post_id ) ) {
		return;
	}
	if ( ! current_user_can( 'edit_post', $post_id ) ) {
		return;
	}
	// nonceの確認と、保存処理
}

使い分け早見表

フック 実行されるタイミング
save_post 投稿タイプを問わず、投稿の保存時(新規投稿画面を開いたときに作られる自動下書きでも実行される)
save_post_{post_type} 指定した投稿タイプの、保存時のみ(save_post より先に実行される)
wp_after_insert_post 投稿に加えて、タームやメタの保存も終わった後(WordPress 5.6以降)

関連項目

wp_insert_post()、add_meta_box()、wp_is_post_revision()、wp_update_post()、current_user_can()

公式リファレンス:save_post | WordPress Developer Resources

コメント

タイトルとURLをコピーしました