検索キーワードを入力
カテゴリーを選択

WordPressのコメントフォームに自作で画像アップロード機能を実装する方法を徹底解説(プラグインなし)

投稿日:2025年09月14日(日)
WordPressのコメントフォームに自作で画像アップロード機能を実装する方法を徹底解説(プラグインなし)|UMENOKI|すぐに仕事で使えるIT技術情報メディア

みなさんこんにちは!エンジニアの高澤です。

今回は、WordPressのコメントフォームに自作で画像アップロード機能を実装する方法を徹底解説したいと思います。

WordPressのコメントフォームでは、通常のデフォルトで画像アップロード機能がありません。コメントフォームから入力できるのはテキストのみとなります。

ただ、このままだと不便な可能性があります。例えば、コメント上でユーザーが会話をする中で、どうしても画像がないと伝わらない内容があったりするかと思います。

そんな時に、WordPressのコメントフォームに画像アップロード機能を追加できたら、ユーザーの要望やサイトの利便性を上げることができるかと思います。

当記事では、このコメントに画像アップロード機能を追加実装する方法について徹底解説いたしますので、よろしければお仕事などでご活用ください。

今回実装する機能について

今回実装する機能について、まず解説したいと思います。

まず実装イメージとしては下図のような形になります。

ファイルを選択できるUIを表示し、クリックすることで画像をアップロードすることができます。

画像をアップした上でコメントを送信することで、下図のようにコメント欄にアップロードした画像が表示されます。

また、今回掲載するサンプルコードでは、コメント機能の一部である「コメント表示条件」にも対応しておりますので、掲載しているサンプルコードをそのままコピペしてお使いできるようになっております。

このように基本的に手順通りにコピペしていただければそのままご利用できるようになっておりますが、ご自身のサイトに合わせてカスタマイズいただいても問題ありません。

それでは次から実装方法について解説いたします。

コメントフォームに画像アップロード機能を追加する実装方法

それでは早速、コメントフォームに画像アップロード機能を追加する方法について解説いたします。

手順通りに進めていただければ無理なく簡単に実装が可能なので、エンジニアの方もご自身でWordPressテーマをカスタマイズすることに挑戦されるブロガーや企業ウェブ担当者の方も安心してご確認いただければと思います。

カスタマイズするテーマを決める(自作テーマでも可)

まず最初に、カスタマイズするテーマを決めていただければと思います。

今回実装例で利用するテーマはWordPressデフォルトテーマの一つのである「Twenty Seventeen」を利用してカスタマイズしたいと思います。

ちなみに先にお伝えしておくのですが、当記事での内容では「Twenty Seventeen」の親テーマを使ってカスタマイズするため、後々「Twenty Seventeen」のテーマアップデートをした場合、今回カスタマイズした内容は強制削除されてしまいますので、あくまでも実装の練習として認識いただいた上で手を動かしていただければと思います。

もし一旦試しに解説通りに実装してみたい方で、ご自身のWordPressに「Twenty Seventeen」がインストールされていなければ、管理画面「テーマ」からインストールしてみてください。

また、もちろんご自身のオリジナルの独自開発したWordPressテーマがあれば、コメント機能をテーマ内に実装していることを前提で、これから解説する手順を参考にして実装してみていただければと思います。

functions.phpに処理コードを追加

まずは最初に、WordPressテーマ内にあるfunctions.phpにコメント送信時の処理と、コメントフォームに画像アップロードUIを追加するためのコードを記述いたします。

下図のように、WordPress管理画面左メニュー「外観」→「テーマファイルエディター」→編集するテーマを選択で「Twenty Seventeen」を選択→「functions.php」で、functions.phpにコードを追加できる状態にしてください。

そして以下のコードを、functions.phpにコピー&ペーストしてください。

<?php
// コメントフォームにファイルアップロードを許可するためenctype追加
function add_comment_form_enctype() {
    echo ' <script>
        document.addEventListener("DOMContentLoaded", function() {
            var form = document.getElementById("commentform");
            if (form) {
                form.setAttribute("enctype", "multipart/form-data");
            }
        });
    </script>';
}
add_action('comment_form', 'add_comment_form_enctype');

function add_comment_image_upload_field() {
    echo '<p class="comment-form-image">
        <label for="comment_image">画像をアップロード:</label>
        <input type="file" name="comment_image" id="comment_image" accept="image/*">
    </p>';
}

// ログイン・ログアウトどちらの状態でも画像アップロードフィールドを表示
add_action('comment_form_after_fields', 'add_comment_image_upload_field'); // ログアウト時
add_action('comment_form_logged_in_after', 'add_comment_image_upload_field'); // ログイン時

function save_comment_image_upload($comment_id) {
    if (
        !empty($_FILES['comment_image']['name']) &&
        !empty($_FILES['comment_image']['tmp_name'])
    ) {
        require_once(ABSPATH . 'wp-admin/includes/file.php');
        require_once(ABSPATH . 'wp-admin/includes/image.php');
        require_once(ABSPATH . 'wp-admin/includes/media.php');

        $uploadedfile = $_FILES['comment_image'];
        $upload_overrides = ['test_form' => false];

        // アップロード前にユーザー権限をチェック
        $user_id = get_current_user_id();
        $requires_moderation = !current_user_can('moderate_comments');

        // ファイルをアップロード
        $movefile = wp_handle_upload($uploadedfile, $upload_overrides);

        if ($movefile && !isset($movefile['error'])) {
            $file_path = $movefile['file'];
            $file_name = basename($file_path);
            $file_type = $movefile['type'];

            // メディアライブラリに登録するための配列を準備
            $attachment = array(
                'post_mime_type' => $file_type,
                'post_title' => preg_replace('/\.[^.]+$/', '', $file_name),
                'post_content' => '',
                'post_status' => 'inherit'
            );

            // メディアライブラリに画像を登録
            $attach_id = wp_insert_attachment($attachment, $file_path);

            // 添付ファイルのメタデータを生成
            $attach_data = wp_generate_attachment_metadata($attach_id, $file_path);
            wp_update_attachment_metadata($attach_id, $attach_data);

            // 承認状態に関係なく、まずは画像を保存
            add_comment_meta($comment_id, 'comment_image_url', esc_url_raw($movefile['url']));
            add_comment_meta($comment_id, 'attachment_id', $attach_id);
            
            // 承認待ちの場合は、その情報も保存
            if ($requires_moderation) {
                add_comment_meta($comment_id, 'pending_image', true);
            }
        }
    }
}

// コメント承認時に画像の表示を有効化
function handle_comment_approval($new_status, $old_status, $comment) {
    if ($old_status !== $new_status && $new_status === 'approved') {
        $pending_image = get_comment_meta($comment->comment_ID, 'pending_image', true);
        if ($pending_image) {
            delete_comment_meta($comment->comment_ID, 'pending_image');
        }
    }
}
add_action('transition_comment_status', 'handle_comment_approval', 10, 3);
add_action('comment_post', 'save_comment_image_upload');

function my_custom_comments($comment, $args, $depth) {
    // コメントの承認状態をチェック
    $comment_approved = $comment->comment_approved;
    
    // 承認待ちの画像かどうかを確認
    $pending_image = get_comment_meta($comment->comment_ID, 'pending_image', true);
    
    // 現在のユーザーが管理者権限を持っているかチェック
    $is_admin = current_user_can('moderate_comments');
    
    // コメント投稿者のIPアドレスを取得(未承認コメントの表示権限チェック用)
    $comment_author_IP = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '';
    $is_comment_author = ($comment_author_IP === $comment->comment_author_IP);
    
    // 承認機能が有効な場合の表示条件:
    // 1. コメントが承認済み、または
    // 2. 管理者が見ている、または
    // 3. コメント投稿者本人が見ている(moderation-hashで確認)
    $show_image = get_option('comment_moderation') ? 
        ($comment_approved === '1' || $is_admin || 
         (isset($_GET['moderation-hash']) && $is_comment_author)) : 
        true;
    
    // カスタムフィールド 'comment_image_url' を取得
    $image_url = get_comment_meta($comment->comment_ID, 'comment_image_url', true);
    
    // コメント表示の開始タグ
    $tag = ($args['style'] == 'div') ? 'div' : 'li';
?>
    <<?php echo $tag ?> <?php comment_class(empty($args['has_children']) ? '' : 'parent') ?> id="comment-<?php comment_ID() ?>">

        <article id="div-comment-<?php comment_ID() ?>" class="comment-body">

            <div class="comment-meta">
                <div class="comment-author vcard">
                    <?php if (0 != $args['avatar_size']) echo get_avatar($comment, $args['avatar_size']); ?>
                    <?php printf(__('<b class="fn">%s</b> <span class="says">says:</span>'), get_comment_author_link()); ?>
                </div>

                <div class="comment-metadata">
                    <a href="<?php echo esc_url(get_comment_link($comment->comment_ID, $args)); ?>">
                        <time datetime="<?php comment_time('c'); ?>">
                            <?php printf(
                                _x('%1$s at %2$s', '1: date, 2: time'),
                                get_comment_date(),
                                get_comment_time()
                            ); ?>
                        </time>
                    </a>
                    <?php edit_comment_link(__('(Edit)'), '<span class="edit-link">', '</span>'); ?>
                </div>
            </div>

            <div class="comment-content">
                <?php comment_text(); ?>

                <?php if ($image_url && $show_image) : ?>
                    <p class="comment-image">
                        <img src="<?php echo esc_url($image_url); ?>" alt="コメント画像" style="max-width: 100%; height: auto;">
                    </p>
                <?php endif; ?>
            </div>

            <?php
            comment_reply_link(array_merge($args, array(
                'add_below' => 'div-comment',
                'depth'     => $depth,
                'max_depth' => $args['max_depth'],
                'before'    => '<div class="reply">',
                'after'     => '</div>'
            )));
            ?>

        </article>
    </<?php echo $tag ?>>
<?php
}

コードは下図のように追加していただくイメージです。

ペーストが完了したら、「ファイルを更新」ボタンをクリックしてコードを保存してください。

これでコメントフォーム送信時の処理とコメントフォームに画像アップロードの機能が追加されました。

コメント表示部分の実装

次に、コメント表示にアップロードした画像を表示する機能部分の実装をしたいと思います。

テーマファイルエディター画面右の「comments.php」を選択してください。

すると下図のようにwp_list_comments()関数が記述されている箇所があるかと思います。この部分のコードを書き換えます。

以下のコードをコピー&ペーストしてコードを上書きして修正してください。

<?php
wp_list_comments(array('callback' => 'my_custom_comments'));

修正後は下図のイメージになります。

ちなみに、wp_list_comments()関数は、記事や固定ページに付けられたコメント一覧を出力するためのテンプレートタグです。

コードの修正が完了したら、適当に投稿ページを確認してみてください。

すると、下図のようにコメントフォームに画像アップロードのUIが追加されているかと思います。

(以下はログアウトした状態の表示になります)

それでは早速コメントフォームから適当に入力してコメント送信してみてください。

すると、下図のように送信したコメントに画像が無事アップロードされて表示されているかと思います。

もしコメントの承認機能をONにしていた場合は、管理者がコメント管理画面からコメントを承認すれば、画像が表示された上でコメントが追加されているかと思います。

管理画面にアップした画像を確認できるように実装

次に、コメント管理画面にて、サイト管理者が送信されたコメントにアップロードされた画像を簡単に確認できるようにする実装をしたいと思います。

この実装を行うことで、もし承認機能をONにしていた場合、アップロードされた画像を事前に確認した上で承認することができるため、セキュリティ的にもサイト上のルール的にも安全に運用することが可能となります。

それでは実装しましょう。

以下のコードをfunctions.phpにコピー&ペーストしてください。

<?php
// 管理画面のコメント一覧にカスタム列を追加
function add_comment_image_column($columns) {
    $columns['comment_image'] = '添付画像';
    return $columns;
}
add_filter('manage_edit-comments_columns', 'add_comment_image_column');

// カスタム列に画像のサムネイルを表示
function custom_comment_column($column, $comment_ID) {
    if ($column === 'comment_image') {
        $image_url = get_comment_meta($comment_ID, 'comment_image_url', true);
        $attachment_id = get_comment_meta($comment_ID, 'attachment_id', true);
        
        if ($image_url && $attachment_id) {
            // 画像のサムネイルを取得
            $thumbnail = wp_get_attachment_image($attachment_id, [100, 100]);
            if ($thumbnail) {
                echo '<a href="' . esc_url($image_url) . '" target="_blank">';
                echo $thumbnail;
                echo '</a>';
            }
        }
    }
}
add_action('manage_comments_custom_column', 'custom_comment_column', 10, 2);

ペーストが完了したら、「ファイルを更新」ボタンをクリックして、WordPress管理画面左メニューの「コメント」にて確認してみてください。

確認すると、下図のように送信済みのコメント一覧の右側に「添付画像」という内容で画像を閲覧できるようになっているかと思います。

これで、運用時の利便性までを意識した上で、コメントフォームに画像アップロード機能を追加する実装は完了です。お疲れ様でした!

意外とそんなに難しくなかったかと思います。

万が一機能がうまく動かなかったりUIなど変更したい場合は、自由にカスタマイズしていただいて問題ありません。

注意!必ず子テーマを作成して実装し直しましょう

今回の解説では例として「Twenty Seventeen」というWordPressのデフォルトテーマを利用してカスタマイズをしました。

ただ、今回カスタマイズしたコードは、そもそも「Twenty Seventeen」の親テーマに対して行ったので、もしテーマのアップデートを行った場合、親テーマであれば全てのファイルやソースコードが新しく作り直されてしまうため、作業した分のコードが強制的に消えてしまうことになります。

そのため、そんな時に必須の手段が「子テーマを作る」ことです。

子テーマを作ることで、親テーマの機能をそのまま引き継ぎつつ柔軟にカスタマイズすることができますし、テーマのアップデートを行ってもそれは親テーマに対してのアップデートになるため、子テーマにはなんの影響もありません。

カスタマイズ時に追加したコードが消えてしまうこともありません。

そのため、ぜひ子テーマを利用して実装し直しましょう。

子テーマの作り方に関しては記事を書いてるので、よろしければご活用ください。

ちなみに自作のテーマで対応している場合は関係ない話になるので、スルーしてください。

まとめ

今回は、WordPressのコメントフォームに自作で画像アップロード機能を実装する方法を徹底解説いたしました。

WordPressのコメントフォームはデフォルトではテキスト入力のみですが、画像アップロード機能を追加することで、より表現力のあるやり取りが可能になります。

テキストだけでは伝わりにくい内容も、画像を添付できればユーザー同士の会話やサイトの利便性を大きく高められます。

当記事で紹介した方法を実装すれば、コメント機能を単なる「感想欄」から、画像も交えた「コミュニケーションの場」へと進化させることができます。

ぜひご自身のサイトに合わせて活用いただいたり、WordPressでのサイト制作やテーマ・プラグイン開発などのお仕事にお役立ていただけましたら幸いです。

執筆者

UMENOKI編集部 高澤 翔汰

歴5年目(2024年8月以降から5年目です)のエンジニアです!
CMSでのサイト構築とWebデザイン制作を兼任して5年目になります。
自作のiOSアプリ(iPhoneアプリ)やWordPressプラグインを開発することもあり、まだまだ現在進行形で勉強中です!

お気軽に皆さんのご要望をお聞かせください!

どんなに些細なことでも構いません!よろしければ記事や当サイトへの「こんな記事があったら仕事とかで役に立つな〜」や「こうだったらもっと役に立つのに!」といったようなご要望等をお気軽にお聞かせください!今後のサービス改善にお役立てさせていただきます!

例1)Reactの技術記事を書いてほしい!
例2)WordPressの使い方とかを初心者向けに解説してほしい!...など

送信と同時にプライバシーポリシーに同意したものとします。