インターネット老人おぢさん

【プログラマー歴10年でもハマる】PHPからメールを送信するのがなぜ難しいのか解説します

最終更新:2021年03月11日 06時08分50秒(初公開:2021年03月03日 08時59分14秒

【プログラマー歴10年でもハマる】PHPからメールを送信するのがなぜ難しいのか解説します

この話はPHPだけでは終わりません。

この記事ではPHPだけの設定に注目して、PHPの外で何をやっているのか解説していきます。

PHPの問題でメールが送れない?

これはほとんどないです。
色々なサイトでPHPのサンプルコードがありますが、見たところサンプルコードに問題があるケースはないです。
あえて言うなら、送信先が間違ってるとか全角半角を含めタイポしてるとかそういう話ぐらい。

備考:PHPでメール送信の方法がいくつかある理由

たとえば、

  • mail 関数
  • mb_send_mail 関数
  • PHPMailer
  • swiftMailer

のような場合です。

一番いい方法

公式では mail , mb_send_mail があるので、メールを送るだけならこれが手っ取り早いです。
が、きちんとしたシステムを作る場合はこれらの関数を使うのは運用面で良くないです。
PHPMailerやswiftMailerを使う方法(PHPのフレームワークが採用)を検討していくのが一般的です。
(ただし、○○Mailer系でも100%安全とは限りませんので、セキュリティ情報には注意しましょう)

プログラミングスクールの課題でメールを送信したい場合

とりあえず送信処理を確認する場合はXampp標準で使えるMercuryやインストールが楽なMailHogなどローカルでメールサーバーを立てる方法が考えられます。
が、この方法はGmailなどローカルホストの外にあるメールアドレスにメールを送信する事ができません。
これはセキュリティ上の問題に依ります。つまり、PHPの外で起きる問題のため、どれだけPHPをこねくり倒してもうまくいきません。

PHPでセキュリティも含めて対応する場合はPHPMailerなどを使う必要があります。

mb_send_mailでできないこと、PHPMailerだとできること

特にMacを使っているユーザーにはクリティカルです。
WindowsならXamppでメールを送信する方法として、Xampp内にsendmailがあり、これを使うことで送信ができます。
Macの場合、Xampp for MacだろうがMAMP for Macだろうがメール送信はMacの標準であるPostfixを使う事になります。
そして、これの設定が非常に難しい!

一応解説しますが推奨しません。

もしsendmail が使えるなら、sendmail.ini に認証情報を書き込んであげればいいです。これはググラビリティも高いのですぐに見つかります。
Macユーザーのようにpostfix を使う場合は、mb_send_mail 関数でメールが送信できない等で検索してもうまくいかないでしょう。
なぜなら、postfixを設定する方法はsendmail.ini を設定するような簡単な話ではなく、main.cf をいじってpasswordをハッシュしてpassword.db を作り、postfixで読み込む必要があるからです。
淡々と書けばこれだけの話ですが、これだけの内容をやるためにどこで間違っているとか何が足りないとか、全部デバッグしないとダメなので相当きついです。
Macでメール送信は諦めたほうがいいんじゃないか? と思うレベルです。
どうしてもMacでメールを送信させたい場合、docker を先に勉強したほうがいいでしょう。

WindowsでもMacでも送信方法を統一するため、mb_send_mail ではなくPHPMailerを使う=composer を使う事になるケースが多いです。
この方法もやり方は色々あるのですが、たどり着くまでにやはり罠があります。
このような問題から「PHPで学ぶとメール送信が難しすぎる」というのが私の持論です。

本記事でも解説がしやすいのでPHPMailerを推奨します。

PHPMailerとは

公式ページ(Github)
composer を使ったりzip圧縮ファイルをダウンロードして require したり色々な方法で使えます。

ここでは、黒い画面に抵抗がある人向けにコマンドプロンプト(ターミナル)を使わないrequire を使って解説します。

理屈はいいからサンプルコードはよ

<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
use PHPMailer\PHPMailer\SMTP;

require('PHPMailer/src/PHPMailer.php');
require('PHPMailer/src/Exception.php');
require('PHPMailer/src/SMTP.php');

/** 以下、変更する場所
 * 今回、mailtrapを使用するので送信設定は(実際には送らないので)何でもOK
 * https://mailtrap.io/inboxes/のMy Inboxをクリックした後に表示される
 * (username):(password)の項目
 * 詳細は後述の画像を参照
 */
$username = '';  // 必須
$password = '';  // 必須
$from = 'dummy@gmail.com';
$to = 'dummy@gmail.com';
$subject = 'タイトル。省略できる';
$body = 'メッセージ。省略できない';
/* 変更する場所 ここまで*/

/* プログラミングスクール受講生の場合は以下も変更する */
$smtp_host = 'smtp.mailtrap.io';  // smtp.gmail.com
$smtp_port = 2525;  // 587
/* 変更する場所 ここまで*/

$mail = new PHPMailer(true);
$mail->CharSet = 'utf-8';  // なくても動くけど日本語が文字化けする

// SMTPサーバ:今回はmailtrap.ioを使用
$mail->isSMTP();
$mail->Host       = $smtp_host;
$mail->SMTPAuth   = true;  // SMTPサーバーの認証情報を使用する
$mail->Username   = $username;  // 上記で入力したユーザ名
$mail->Password   = $password;  // 上記で入力したパスワード
$mail->SMTPSecure = 'tls';  // mailtrapはtlsを使用しているので固定
$mail->Port       = $smtp_port; // mailtrapのTCPポートは2525で固定

// メール
$mail->setFrom($from); // 送信元
$mail->addAddress($to);   // 送信先
$mail->Subject = $subject;
$mail->Body = $body;
$mail->send();

よく分からない場合は、 $username$password を入れれば送信できる状態にしました。
PHPだけではありませんが、mailtrapのアカウント(無料)を作ればすぐに送信処理が確認できます。
Gmailを使う方法も紹介されていますが、やり方が複雑になっているので送信確認をしたいだけならmailtrapで良いと思います。

PHPMailerをダウンロードする

公式ページ からダウンロードできます。
緑のボタン「Code」から「Download ZIP」を押すとダウンロードが始まります。
緑のボタンが表示されていない方は、ブラウザ画面を広げてください。拡大ではないです。

ダウンロードした場所は把握しておきます。

PHPMailerをインストールする

今回は手動でダウンロードしたので、これをPHPファイルから使えるようにしましょう。
ファイルパスの説明は省略しますが、概ねこのように書くとインストール(PHPファイルから使えう事)ができます。

use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
use PHPMailer\PHPMailer\SMTP;

require('PHPMailer/src/PHPMailer.php');
require('PHPMailer/src/Exception.php');
require('PHPMailer/src/SMTP.php');

ファイルツリーは以下のように作成しています。

.
├── index.php    (今回作るファイル)
├── PHPMailer
│   ├── (省略)
(省略)

PHPMailerを解凍した場所にindex.phpを作ってソースコードをコピーしてください。
もしXamppやMAMPなどを使っている場合は、それぞれのhtdocs以下に移動させましょう。

メールを送信する

サンプルコードにコメントを書いているので、それを見ながらやってみてください。

解説

Q. localhostからメールを送りたい

A.セキュリティ上の問題で外部アドレスにメール送信ができなくなりました
ローカルからメールを送れる時期もありましたが、架空のメールアドレスを作ってやりたい放題できたため、今はしっかり対策されています。
送信ができなくなったという事を知らない方も、悪用対策だと認識されてはいないようです。

Q.localhostでもメールを送るには?

A. 厳密にはSMTPサーバーをlocalhostにメール送信の機能が制限された、というのが正解です。
localhostからlocalhostにメールを送ることはできます。
ただし、localhostからGmailやYahooなどには送れません。

Q. メール送信の問題点

あまりにも長くなったんでまとめました。

© 2020-2021のむらやごろう(@elder_uncle)

当サイトの全てのコンテンツを転載・無断での引用もお断りしています。