メインコンテンツへスキップ

Tech

Contact Form 7 ファイル添付の設定方法と落とし穴

Contact Form 7 でファイル添付を設定する手順を、[file]タグ・mailタブ・サーバー側の上限の3点に分けて解説します。
確認画面と併用したときにつまずく箇所と、送信後にファイルが残らない理由も実装ベースで説明します。

見積書や求人応募の履歴書など、フォームにファイル添付が必要になる場面は多いです。
Contact Form 7 はファイル添付に標準対応していますが、設定箇所が2か所に分かれているうえに初期値がかなり厳しいため、「エラーは出ないのにファイルが届かない」という相談が絶えません。

先に結論だけ書きます。
うまくいかないときに見る場所は3か所です。

  1. フォームタグ側([file]のlimitとfiletypes)
  2. mailタブの「ファイル添付」欄(メールタグの記入漏れ)
  3. サーバー側の上限(upload_max_filesizepost_max_size

以下、順に設定していきます。

方法1:[file]タグとmailタブの添付ファイル欄をそろえる

まずフォームタブに、ファイル入力欄を置きます。

[file your-file limit:5mb filetypes:pdf|docx|xlsx|jpg|jpeg|png]

limitを書かない場合の上限は1MBfiletypesを書かない場合の許可形式はaudio/|video/|image/*です。
つまり初期状態のままだと、PDFもWordファイルもすべて弾かれます。
ご相談の半分はここで終わります。
必須にする場合は[file* your-file ...]と書きます。

次が忘れられがちな2か所目です。
mailタブを開き、本文ではなく「ファイル添付」欄にメールタグを書きます。

[your-file]

本文中に[your-file]と書いてもファイル名の文字列が入るだけで、添付にはなりません。
ファイル欄が複数ある場合は、改行して並べます。

[your-file]
[your-file-2]

なお、1通のメールに添付できる合計サイズの上限は25MBです。
3MBのファイルを10個受け取る設計にすると、この壁に当たります。

方法2:サーバー側の上限をそろえる

limit:5mbと書いても、サーバーが2MBまでしか受け付けない設定なら5MBのファイルは通りません。
しかもこの場合、フォーム側には分かりにくいエラーしか出ません。
まず現在値を確認します。
管理画面に一時的に表示させるのが手軽です。

// functions.php(確認が済んだら削除してください)
add_action( 'admin_notices', function () {
	if ( ! current_user_can( 'manage_options' ) ) {
		return;
	}
	printf(
		'<div class="notice notice-info"><p>upload_max_filesize=%s / post_max_size=%s / WordPress上限=%sMB</p></div>',
		esc_html( ini_get( 'upload_max_filesize' ) ),
		esc_html( ini_get( 'post_max_size' ) ),
		esc_html( (string) round( wp_max_upload_size() / 1024 / 1024, 1 ) )
	);
} );

上限を引き上げる場合は、post_max_sizeupload_max_filesizeより大きく取るのが要点です。
フォームはファイル以外の入力値も一緒に送るため、同値にすると境界付近で落ちます。

; .user.ini(PHPがFastCGIで動く一般的なレンタルサーバー)
upload_max_filesize = 10M
post_max_size = 12M
max_file_uploads = 20

Apacheのmod_phpで動いている場合は.htaccessに書きます。

php_value upload_max_filesize 10M
php_value post_max_size 12M

どちらが有効かはサーバーによります。
反映されない場合はもう一方を試すか、サーバー管理画面側の上限設定を確認してください。

方法3:確認画面・マルチステップと併用する

ここからが実装で分かった話です。
入力内容を確認してから送信する画面をファイル添付と併用すると、確認画面には次のように表示されます。

添付ファイル: C:\fakepath\見積書_20260901.pdf

これは不具合ではなく、ブラウザの仕様です。
input[type="file"]valueは、セキュリティ上の理由で実際のパスを返さず、C:\fakepath\という固定文字列にファイル名をつないだ値になります。
確認画面は各入力欄のvalueを読んで表示するため、そのまま出てしまいます。
当社の Frontierline Forms でも、確認ステップは入力欄を走査して値を表示する実装のため、同じ表示になります(v2.1.1で確認済み)。

実務では、次のスクリプトを1本入れて表示だけ直します。
filesプロパティから本当のファイル名を取り出して差し替える処理です。

( function () {
	'use strict';
	var FAKE = /^[A-Za-z]:\\fakepath\\/;

	function realNames( form ) {
		var map = {};
		form.querySelectorAll( 'input[type="file"]' ).forEach( function ( input ) {
			if ( ! input.files || ! input.files.length ) {
				return;
			}
			map[ input.value ] = Array.prototype.map.call( input.files, function ( f ) {
				return f.name;
			} ).join( '、' );
		} );
		return map;
	}

	function repaint( form ) {
		var map = realNames( form );
		form.querySelectorAll( '.cf7mp-confirm__value' ).forEach( function ( cell ) {
			var text = cell.textContent.trim();
			if ( ! FAKE.test( text ) ) {
				return;
			}
			cell.textContent = map[ text ] || text.replace( FAKE, '' );
		} );
	}

	document.addEventListener( 'DOMContentLoaded', function () {
		document.querySelectorAll( '.wpcf7-form' ).forEach( function ( form ) {
			new MutationObserver( function () {
				repaint( form );
			} ).observe( form, { childList: true, subtree: true } );
		} );
	} );
}() );

確認画面は「次へ」を押した時点で組み立て直されるため、MutationObserverで描画のたびに走らせるのが安全です。
他社製の確認画面プラグインをお使いの場合は、.cf7mp-confirm__valueの部分を、そのプラグインが値を出力しているクラス名に置き換えてください。

もう1点、こちらは仕様として理解しておく必要があります。
ページ遷移をともなう確認画面では、選択済みのファイルは保持できません
ブラウザがファイル入力欄への値の代入を禁じているためです。
ファイル添付を含むフォームでは、画面を再読み込みしない方式(同一ページ内でステップを切り替える方式)を選ぶのが安全です。
確認画面の作り方はContact Form 7 に確認画面を追加する方法、ステップ分割はContact Form 7 でマルチステップフォームを作る方法にまとめています。

確認画面とファイル添付の併用

確認画面・マルチステップは無料版で追加できます

Frontierline Forms は、Contact Form 7 に確認画面とマルチステップを追加する公式ディレクトリ配布のプラグインです。同一ページ内でステップを切り替える方式のため、ファイル添付を含むフォームでも選択済みのファイルが消えません。

無料版をダウンロードする

送信後にファイルが残らない理由

アップロードされたファイルはwp-content/uploads/wpcf7_uploadsに一時保存され、メール送信の処理が終わると削除されます。
つまりサーバーには残りません
「あとから管理画面で見返せると思っていた」という運用の行き違いは、ここで起きます。

送信内容をデータベースに保存するタイプのプラグインを入れていても、保存されるのは送信データ(テキスト)であり、添付ファイルの実体は含まれません。
当社プラグインの保存処理も、wpcf7_mail_sentのタイミングで送信データをJSON化して保存する実装です。
ここから2つの実務的な含意が出ます。

  • ファイルの原本は、届いたメール側で保管するのが原則になる
  • 保存の起点がメール送信の成功であるため、メールが送れなかった送信は記録にも残らない

後者は特に重要です。
添付ファイル付きのメールはサイズが大きく、送信に失敗しやすい部類に入ります。
ファイル添付を導入する前に、メールが確実に届く状態を作っておいてください。
原因の切り分けはContact Form 7 のメールが届かないときの原因と対処、送信内容の保存についてはContact Form 7 の送信内容をデータベースに保存する方法で解説しています。

まとめ

ファイル添付でつまずく箇所は、ほぼ次の5つに収束します。

  1. filetypesの初期値が画像・音声・動画のみで、PDFが弾かれている
  2. limitの初期値が1MBのまま
  3. mailタブの「ファイル添付」欄が空
  4. サーバー側のupload_max_filesizepost_max_sizeが足りない、または逆転している
  5. ページ遷移をともなう確認画面で、選択済みのファイルが消える

1から3はフォームの設定だけで解決します。
4はサーバー、5はフォームの設計です。
設定を直しても届かない場合は、ファイルの問題ではなくメール到達性の問題である可能性が高いです。

Frontierline Forms

確認画面・マルチステップ・送信履歴の保存を1つで

確認画面、ステップ分割、送信履歴のデータベース保存とCSV書き出しまで、無料版に含まれています。通知やメールの出し分けなど、運用を自動化する機能は上位版でご利用いただけます。

無料版をダウンロードする 上位版の機能を見る

よくある質問

Contact Form 7 のファイル添付は、初期状態で何MBまで送れますか。

[file]タグのlimitオプションを書かない場合、上限は1MBです。
あわせてfiletypesの初期値がaudio/*|video/*|image/*のため、PDFやWordファイルは指定を足さないと弾かれます。
サーバー側のupload_max_filesizepost_max_sizeも上限として効きます。

添付ファイルがメールに付いてきません。

mailタブの「ファイル添付」欄にメールタグを書き忘れているケースがほとんどです。
[file your-file]なら、ファイル添付欄に[your-file]と記入します。
本文側にメールタグを書いてもファイルは添付されません。

送信されたファイルはサーバーに保存されますか。

保存されません。
アップロードされたファイルはwp-content/uploads/wpcf7_uploadsに一時的に置かれ、メール送信の処理が終わると削除されます。
ファイルを手元に残したい場合は、届いたメールの添付ファイルを保管する運用になります。

確認画面にファイル名ではなくC:\fakepathと表示されます。

ブラウザの仕様で、ファイル入力欄の値がC:\fakepath\ファイル名という文字列になるためです。
確認画面の表示を書き換える小さなJavaScriptで、実際のファイル名だけを表示できます。
本記事の方法3にコードを掲載しています。

参考