「CSVで顧客管理してるけど、どうやってメール送ったらいい?」
「案件でメール一括配信が必要だけど、ライブラリや高額なサービスは使いたくない…」
そんな声に応えて、今回紹介するのは
PHPとCSVを使って、自分だけのメール配信スタンドを構築する方法です。
案件でよくある「メールを一括で送りたい」「開封やクリックのログも取りたい」
といったニーズに対して、すべて自作で対応できるノウハウを詰め込みました。
本記事で学べること
- 顧客リスト(CSV)をインポートしてDBに保存する方法
- ユーザー一覧をHTMLテーブル表示し、CSVとしてエクスポートする機能
- PHPMailerを使った一括メール送信と配信ログの記録
- 開封ログやクリックログをPHPで記録する仕組み
- 実務でも使えるテンプレート構成の考え方
完成イメージ
最終的には、以下のようなシステムが完成します。
- CSVで顧客情報をアップロード
- 管理画面で送信対象と本文を設定
- 一括でメール配信(PHP)
- 開封されたか・リンクがクリックされたかを記録
- cronと組み合わせれば自動配信にも応用可!
ファイル構成(実用的な分離型)
mail-stand/
├─ index.php ← メール送信UI&配信ボタン
├─ upload.php ← CSVアップロード処理
├─ send.php ← メール配信処理(PHPMailer使用)
├─ logs/
│ └─ open_log.php ← 開封ログ記録用(画像読み込み)
│ └─ click_log.php ← リンククリックログ記録
├─ uploads/ ← CSV一時保存用ディレクトリ
├─ csv/
│ └─ sample.csv ← サンプルCSV
├─ db.php ← DB接続用ファイル
├─ css/
│ └─ style.css ← スタイルファイル
├─ js/
│ └─ script.js ← バリデーション・確認処理など
└─ db.sql ← 初期テーブル作成用SQL
STEP1|CSVファイルをインポートしてDBに保存
まず最初に行うのは、「配信対象のユーザーリスト(名前・メールアドレスなど)」をCSVファイルでアップロードし、データベースに保存する処理です。
CSVを使うことで、外部管理されたリスト(Excelなど)をそのまま流用でき、
クライアント側でも簡単に編集・追加できるのが利点です。
実装内容の詳しい解説
まず、CSVファイルをアップロードするためのHTMLフォームを作成し、アップロード先の upload.php
にファイルを送信します。
<!-- index.php または uploadフォームを表示するファイルに記述 -->
<form action="upload.php" method="post" enctype="multipart/form-data">
<label for="csvFile">CSVファイルを選択:</label>
<input type="file" name="csvFile" accept=".csv" required>
<button type="submit">アップロード</button>
</form>
次に、upload.php
側では以下のような手順で処理を行います:
<?php
require_once 'db.php'; // DB接続用ファイル
if (isset($_FILES['csvFile']) && $_FILES['csvFile']['error'] === UPLOAD_ERR_OK) {
$fileTmpPath = $_FILES['csvFile']['tmp_name'];
$handle = fopen($fileTmpPath, 'r');
if ($handle !== false) {
// 1行目はヘッダーと仮定してスキップ
fgetcsv($handle);
while (($data = fgetcsv($handle, 1000, ',')) !== false) {
$name = trim($data[0]);
$email = trim($data[1]);
// 簡単なバリデーション
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
continue;
}
// 重複チェックと挿入処理
$stmt = $pdo->prepare("SELECT COUNT(*) FROM subscribers WHERE email = ?");
$stmt->execute([$email]);
if ($stmt->fetchColumn() == 0) {
$insert = $pdo->prepare("INSERT INTO subscribers (name, email) VALUES (?, ?)");
$insert->execute([$name, $email]);
}
}
fclose($handle);
echo "インポートが完了しました。";
} else {
echo "ファイルの読み込みに失敗しました。";
}
} else {
echo "ファイルのアップロードに失敗しました。";
}
このように、CSVファイルを1行ずつ読み取りながら、
名前・メールアドレスの形式チェック&重複確認の上でDBにINSERTする処理を行っています。
補足:テーブル構造の例
あらかじめ以下のようなDBテーブルを用意しておきましょう(db.sql
などに含める):
CREATE TABLE subscribers (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100),
email VARCHAR(255) UNIQUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
この構造で、同じメールアドレスが2重登録されるのを防ぐことができます。
※CSVファイルの扱いやエラー処理の考え方については、以前公開した記事「【実務に必須】CSVインポート&エクスポート機能をPHPで実装!」でも詳しく解説しています。

実装の流れ
- CSVファイルを選択&アップロード
- アップロードしたファイルを読み込む
- 1行ずつDB(MySQL)にINSERTして保存
- 重複チェックやバリデーション処理も含める
STEP2|データを一覧表示&CSVエクスポート機能を追加しよう
このステップでは、CSVで登録したユーザー情報を一覧表示することで管理しやすくし、
さらにそのリストをCSV形式でダウンロードできる「エクスポート機能」を実装していきます。
HTMLでユーザー一覧をテーブル表示し、ボタン1つで現在の登録者全員のデータをCSVとして出力できるようにすることで、
バックアップや再利用にも便利な管理画面を構築していきます。
STEP1で保存したユーザー情報(name, email)を、一覧画面で表示できるようにしていきます。
また、管理画面から「現在のリストをCSVとしてダウンロード」できるよう、エクスポート機能も同時に実装します。
一覧表示は、送信対象の選定や重複チェックにも役立つため、実務でも非常に重宝されます。
実装内容の流れ
- DBから登録済みユーザーを取得
- HTMLテーブルで一覧表示
- 「CSVダウンロード」ボタンを追加
- CSVファイルを動的に生成して出力
index.php(一覧表示+ダウンロードボタン)
<?php
require_once 'db.php';
$stmt = $pdo->query("SELECT * FROM subscribers ORDER BY created_at DESC");
$subscribers = $stmt->fetchAll();
?>
<h2>登録済みユーザー一覧</h2>
<a href="export.php" target="_blank">📄 CSVダウンロード</a>
<table border="1" cellpadding="8">
<tr>
<th>名前</th>
<th>メールアドレス</th>
<th>登録日時</th>
</tr>
<?php foreach ($subscribers as $row): ?>
<tr>
<td><?= htmlspecialchars($row['name']) ?></td>
<td><?= htmlspecialchars($row['email']) ?></td>
<td><?= $row['created_at'] ?></td>
</tr>
<?php endforeach; ?>
</table>
export.php(CSVエクスポート処理)
<?php
require_once 'db.php';
$stmt = $pdo->query("SELECT name, email FROM subscribers");
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
// ヘッダー情報
header('Content-Type: text/csv');
header('Content-Disposition: attachment;filename=subscribers.csv');
$output = fopen('php://output', 'w');
fputcsv($output, ['名前', 'メールアドレス']);
foreach ($rows as $row) {
fputcsv($output, [$row['name'], $row['email']]);
}
fclose($output);
exit;
このコードでは、PHPを使ってデータベースから登録済みのユーザーを取得し、HTMLテーブルとして表示しています。
その上で、「CSVダウンロード」リンクをクリックすると、export.php が実行され、一覧データが動的にCSV形式で出力されます。
補足ポイント
- 登録ユーザー情報の可視化により、配信対象の確認や重複チェックがしやすくなる
- CSV出力はバックアップ用途や他サービスへの移行にも有効
- ユーザーにデータ提供する際にもそのまま使えるフォーマット
次のSTEPでは、一覧から対象を選んで実際にメールを一括送信する処理へと進んでいきます。
STEP3|一括メール送信機能を作ろう(PHPMailer使用)
いよいよ実務に直結する「一括メール送信」機能を実装していきます。
ここでは、PHPMailerというライブラリを使って、登録済みのユーザー全員に対して一括でメールを送信できるようにします。
送信対象の読み込み・本文の入力・送信の実行・ログ保存という一連の流れを、フォームとPHPスクリプトで構成します。
STEP1・STEP2で用意したデータベースと一覧画面を活かし、
送信対象を選び、PHPMailerライブラリを使って一括送信できる機能を作成します。
完全ガイドはnoteにて公開中!
今回のガイドは、サンプルコード付き/実装ステップ付き/コピペOKの内容で
noteにて公開中です👇
このスキルを身につけるとどうなる?
このスキルは、ただの「一括送信ツール」を作るだけではありません。
・クライアントのCRMと連携した独自配信ツールを作れる
・PHPでログ管理・集計ができる
・低コストで自社運用できるマーケ基盤を構築できる
つまり、あなたの技術が「売れる形」になるのです。
定期購読でさらに深く学べます!
noteのメンバーシップでは、以下の特典をご用意しています。
- あなたのコードを添削&アドバイス(HTML/CSS/JS/PHP対応)
- Zoom相談(月1回)で実装の悩みを解決
- 実務向けテンプレートの先行配布
- ChatGPT活用ノウハウ&プロンプト共有
「もう一歩踏み込みたい」
「案件対応力を強化したい」
そんな方は、ぜひご参加ください!