説明
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()

コメント