2026年5月20日
2026年5月20日
Contact Form 7のファイルアップロード設定|拡張子・サイズ上限・メール添付と保存
Contact Form 7(以下 CF7)では、フォームに file タグを置くと、利用者からファイルを受け取れます。受け取ったファイルはメールに添付して届けるのが基本の使い方です。この記事では、タグの書き方、受け付ける拡張子とサイズの指定、PHP 側の上限、メールへの添付、ファイルをサーバーに残す方法を説明します。内容は2026年10月時点の CF7 のソースコードと公式の説明に基づいています。
よくある症状と原因
| 症状 | 主な原因 |
|---|---|
| PDF や Word を送ろうとすると「許可されていないファイル形式」という趣旨のエラーになる | filetypes を指定していない(既定では画像・音声・動画だけを受け付ける) |
| 1MB を少し超えるファイルで「ファイルが大きすぎる」という趣旨のエラーになる | limit を指定していない(既定の上限は 1MB) |
limit を大きくしたのに送信に失敗する |
PHP の upload_max_filesize・post_max_size や Web サーバーの上限が小さい |
| メールは届くがファイルが添付されていない | 「メール」タブの「ファイル添付」欄にタグを書いていない |
| 送信後にサーバーのどこにもファイルが残っていない | CF7 は添付に使ったあと一時ファイルを削除する仕様 |
fileタグをフォームに追加する
「お問い合わせ」→ 対象フォームの編集画面で、「フォーム」タブのタグ生成ボタン「ファイル」から挿入するか、次のように直接書きます。
<label>添付ファイル(PDF・Word・画像、5MBまで)
[file* your-file limit:5mb filetypes:pdf|doc|docx|jpg|jpeg|png]</label>
| 書き方 | 意味 |
|---|---|
file* |
* を付けると必須項目になる。任意にするなら file |
your-file |
フィールド名。メールのタグ [your-file] として使う |
limit:5mb |
1ファイルの最大サイズ。数字だけならバイト、kb・mb を付けられる。指定しないと 1MB |
filetypes:… |
受け付ける形式。複数あれば縦棒(パイプ記号)で区切る。拡張子のほか image/* のような MIME タイプも書ける |
filetypes を省略したときに受け付けるのは、image/*・audio/*・video/*(画像・音声・動画)です。PDF や Office 文書を受け取るなら、filetypes に明示します。
file タグには複数ファイルを選ばせるオプションがありません。複数のファイルを受け取るときは、フィールドを分けて置きます。
[file your-file-1 limit:10mb filetypes:pdf|jpg|jpeg|png]
[file your-file-2 limit:10mb filetypes:pdf|jpg|jpeg|png]
PHPとWebサーバーの上限を確認する
limit は CF7 の中での上限です。その前に PHP と Web サーバーの上限で止まると、CF7 の設定を大きくしても受け取れません。次の値が、受け取りたいサイズより大きいかを確認します。
| 層 | 項目 |
|---|---|
| PHP | upload_max_filesize(1ファイル)、post_max_size(送信全体。複数ファイルなら合計より大きく) |
| Nginx | client_max_body_size(既定値 1m) |
| Apache | LimitRequestBody(2.4.54 以降の既定値は 1GiB) |
PHP の値は「ツール」→「サイトヘルス」→「情報」タブの「サーバー」で確認できます。変更方法は PHP の動かし方(PHP-FPM か mod_php か)やレンタルサーバーかどうかで変わり、PHP-FPM の構成では .htaccess の php_value は効きません。詳しい手順はWordPressのメディアアップロードが失敗・タイムアウトする原因と直し方を参照してください。
メールに添付する場合は、メールサーバーや受け取る側のメールサービスにも添付サイズの上限があります。大きなファイルを受け付けると、フォームの送信は成功してもメールが届かないことがあります。limit はメールで届けられる大きさに抑えるのが無難です。
メールにファイルを添付する
フォーム編集画面の「メール」タブの下のほうにある「ファイル添付」欄に、フィールド名のタグを書きます。複数あれば1行に1つずつ書きます。
[your-file-1]
[your-file-2]
メール本文に [your-file] と書いた場合に出力されるのは、ファイル名だけです。ファイル本体は「ファイル添付」欄に書いたときだけ添付されます。
「メール (2)」(送信者への自動返信)を使う場合、そちらの「ファイル添付」欄には何も書かないでおくと、送られたファイルを送信者に送り返さずに済みます。
アップロードされたファイルの扱い(一時フォルダー)
CF7 は受け取ったファイルを、一時フォルダー wp-content/uploads/wpcf7_uploads/ の下に、乱数の名前のサブフォルダーを作って置きます。この一時フォルダーには、Apache からの直接アクセスを拒否する .htaccess が自動で作られます。ファイル名に、スクリプトとして実行されうる拡張子が含まれる場合は、名前を変えて置く処理もあります。
一時ファイルは、送信の処理(メールの送信)が終わると削除され、取り残された古いファイルも後の処理で掃除されます。そのため、CF7 だけではファイルはサーバーに残りません。
Nginx では .htaccess が効かないため、一時フォルダーへの直接アクセスを Nginx の設定で拒否しておきます。
location ^~ /wp-content/uploads/wpcf7_uploads/ {
deny all;
}
一時フォルダーの場所は、wp-config.php で定数 WPCF7_UPLOADS_TMP_DIR を定義すると変えられます。値は wp-content からの相対パスで書き、wp-content の外は指定できません。
送信されたファイルをサーバーに保存する
メールの添付だけでなくサーバーにも残したい場合は、メール送信の直前に実行されるアクション wpcf7_before_send_mail で、一時ファイルを別のフォルダーへコピーします。
WPCF7_Submission::get_instance()->uploaded_files() が返すのは、フィールド名をキー、ファイルのパスの配列を値とする配列です(値は1つのパスの文字列ではありません)。そのため、2重のループで取り出します。
次のコードを wp-content/mu-plugins/cf7-save-uploads.php として保存します(mu-plugins フォルダーが無ければ作ります)。テーマの functions.php に書いても動きますが、テーマを替えると止まります。
<?php
/**
* Plugin Name: CF7 添付ファイルの保存
* Description: 指定したフォームで送られたファイルを uploads/cf7-saved/ に保存する。
*/
add_action( 'wpcf7_before_send_mail', function ( $contact_form ) {
// 対象フォームのID(フォーム一覧のショートコードにある id の数字)
$target_form_id = 123;
if ( $target_form_id !== (int) $contact_form->id() ) {
return;
}
$submission = WPCF7_Submission::get_instance();
if ( ! $submission ) {
return;
}
$uploads = wp_upload_dir();
$base = trailingslashit( $uploads['basedir'] ) . 'cf7-saved';
$dir = $base . '/' . gmdate( 'Y/m' );
// 保存先を作る(親フォルダーも含めて作成)
if ( ! wp_mkdir_p( $dir ) ) {
error_log( 'cf7-save-uploads: cannot create ' . $dir );
return;
}
// Apache で直接ダウンロードされないようにする
if ( ! file_exists( $base . '/.htaccess' ) ) {
file_put_contents( $base . '/.htaccess', "Require all denied\n" );
}
if ( ! file_exists( $base . '/index.php' ) ) {
file_put_contents( $base . '/index.php', "<?php\n// Silence is golden.\n" );
}
foreach ( $submission->uploaded_files() as $field => $paths ) {
foreach ( (array) $paths as $path ) {
// 推測されにくい名前にして、同名があれば番号を付ける
$name = wp_generate_password( 12, false ) . '-' . wp_basename( $path );
$name = wp_unique_filename( $dir, $name );
if ( ! copy( $path, $dir . '/' . $name ) ) {
error_log( 'cf7-save-uploads: copy failed for field ' . $field );
}
}
}
} );
$target_form_id は、フォーム一覧に表示されるショートコード [contact-form-7 id="…"] の id に合わせます。CF7 のバージョンによっては id が英数字のハッシュで表示されますが、その場合はフォーム編集画面の URL にある post= の数字が id() の値です。
保存先の cf7-saved は公開フォルダー(uploads)の下なので、Nginx では次のように直接アクセスを拒否します。
location ^~ /wp-content/uploads/cf7-saved/ {
deny all;
}
保存したファイルは、SFTP などで取り出します。個人情報を含むことが多いので、保存期間を決めて古いものを削除してください。
セキュリティ上の注意
filetypesは必要な形式だけに絞る。php・phtml・js・exe・sh・svgなど、実行やスクリプトにつながる形式は受け付けない- CF7 の一時フォルダーと、自分で作った保存先の両方で、Web からの直接アクセスを拒否する(Apache は
.htaccess、Nginx はlocationでdeny all) - 受け取ったファイルを開く担当者の PC では、ウイルス対策ソフトを有効にしておく
- スパム送信でファイルが大量に届くのを防ぐため、reCAPTCHA などのスパム対策を併用する
まとめ
[file* your-file limit:5mb filetypes:pdf|jpg|png]の形で書く。limitの既定は 1MB、filetypesの既定は画像・音声・動画だけ- PHP の
upload_max_filesize・post_max_sizeと Web サーバーの上限を、limitより大きくする - ファイルを添付するには「メール」タブの「ファイル添付」欄にタグを書く。本文のタグはファイル名だけになる
- CF7 は一時ファイルを送信後に削除する。残すなら
wpcf7_before_send_mailでコピーし、保存先への直接アクセスを拒否する
関連記事: