vdeep

*

vdeepはプログラミング、IT、Web技術、ライフハックの事などなどを管理人okutaniがつぶやくブログです。月間13万PV〜。

PHPMailerを日本語で便利につかう「NPHPMailer」作ってみた

      2017/02/01

LINEで送る
Pocket

nphpmailer
こんにちは、okutani(@okutani_t)です。PHPでメール機能を実装するとき、『PHPMailer』を使うと便利ですね。WordPress, Drupalなどにも使われている実績のあるライブラリです。

このPHPMailerを仕事で使う機会があったのですが、デフォルトで日本語に対応していなかったので『NPHPMailer』というラッパークラスを作ってみました。Nは日本語のNです(安直)。ご自由に使ってやってください。

もともと『JPHPMailer』というラッパークラスがあり有名らしいのですが、そっちは使ったことはないです。気になる方は調べてみてください。

NPHPMailerは下記GitHubで公開しています。

LINKokutani-t/NPHPMailer

また、導入にはComposerを利用する必要があります。Composerについて詳しく知りたい方は以下の過去記事を参考にしてください。

[PHP]Composerを導入&はじめてのパッケージインストールまで
こんにちは、okutani(@okutani_t)です。『Composer』というツールを使うことで、PH...
2016-02-19 18:22
はてブ

では、NPHPMailerの導入方法から使い方までを解説していきます。

※追記: 導入方法をComposerでできるようにリファクタリングしました。それに合わせて記事も改変しています[2017/01/31]

スポンサーリンク

NPHPMailerの導入方法

まずは、NPHPMailerの導入方法について説明していきます。

利用したいプロジェクトに「composer.json」を、以下の内容で作成します。

{
    "require": {
        "okutani-t/nphpmailer": "~1.0"
    }
}

上記ではNPHPMailerのみを記述していますが、最新版のPHPMailerが同時にインストールされます。

以下のコマンドでインストールを実行。

$ composer install

vendor以下にPHPMailer, NPHPMailerが設置されました。

あとは利用したいプロジェクトでvendor/autoload.phpを呼べばOKです。

<?php
require __DIR__ . "/vendor/autoload.php";

これでNPHPMailerを使う準備が整いました。

NPHPMailerの使い方

NPHPMailerの使い方を説明します。

メール送信をおこないたい場所で、次のように利用します。

<?php
require __DIR__ . "/vendor/autoload.php";
use OkutaniT\NPHPMailer;

NPHPMailer::_()
    #->setSMTP(ホスト, ユーザー, パスワード) // サーバーで設定していたら不要
    ->setFrom(差出人)
    ->addAddress(宛先)
    ->setSubject(件名)
    ->setBody(内容)
    ->send();

NPHPMailerを読み込み、『_()』メソッドでインスタンスを生成しています。

それ以降のメソッドは、ほぼほぼPHPMailerの仕様ままです。

サーバーでSMTPの設定をしていたら「setSMTP()」は不要です。HTMLメールを使いたい場合は「isHTML(true)」を途中で挟んでください。

チェーンメソッドを使うことで簡潔に利用できるようにしてみました。すっきり。

実例として、「相手(自動返信用)と自分(確認用)へメール送信をおこなう」流れを一通り紹介しておきます。POSTで相手の名前とメールアドレスが渡されたと仮定しています。

$from      = "from@example.com";
$to        = [
  "myaddress@example.com"
];
$reply     = $_POST["email"];

$mySubject = "お問い合わせがありました";
$myBody    = "名前: " . $_POST["name"] . "\n" .
"メールアドレス: " . $_POST["email"];
$toSubject =  "[自動返信]お問い合わせありがとうございます";
$toBody    =  "以下の内容でメールを送信しました。\n\n" .
"名前: " . $_POST["name"] . "\n" .
"メールアドレス: " . $_POST["email"] . "\n" .
"今後ともよろしくお願いいたします。";

// 自分宛
NPHPMailer::_()
  ->setSMTP("smtp.gmail.com", "〇〇@gmail.com", "Gmailのパスワード") # gmailの場合
  ->setFrom($from)
  ->addAddress($to)
  ->setSubject($mySubject)
  ->setBody($myBody)
  ->send();

// 相手宛(自動返信用)
NPHPMailer::_()
  ->setSMTP("smtp.gmail.com", "〇〇@gmail.com", "Gmailのパスワード")
  ->setFrom($from)
  ->addAddress($reply)
  ->setSubject($toSubject)
  ->setBody($toBody)
  ->send();

差出人、宛先、HTMLはオフに、件名とメール本文の内容を設定してメール送信を実行しています。これを単純に、相手と自分宛に送信実行しています。

addAddress()」の送信先の情報は、文字列と配列両方とれるようにしてあります。

GmailのSMTPを使う場合

もし、GmailのSMPTを使いたい場合は、「setSMTP()」を次のように設定してください。

->setSMTP("smtp.gmail.com", "〇〇@gmail.com", "Gmailのパスワード")

GmailのSMTPを使う場合、差出人が「〇〇@gmail(利用しているGmailのアカウント)」になるのと、「安全性の低いアプリ – アカウント設定」でアクセスをオンにしておく必要がある点に注意してください。

では次に、NPHPMailerの中身をかんたんに解説していきます。

NPHPMailerの中身解説

NPHPMailerの中身は次のとおりです(冒頭のGitHubからも確認できます)。

<?php
/**
 * PHPMailerを日本語用に拡張するラッパークラス
 *
 * @author okutani
 * @package NPHPMailer
 */
namespace OkutaniT;
use PHPMailer;
class NPHPMailer extends PHPMailer
{
    function __construct()
    {
        parent::__construct();
        // HTMLメールは初期値false
        parent::isHTML(false);
        // タイムゾーン設定
        date_default_timezone_set('Asia/Tokyo');
        // 文字エンコーディングの設定
        $this->CharSet  = "UTF-8";   // 文字セット(デフォルトは'ISO-8859-1')
        $this->Encoding = "base64";  // エンコーディング(デフォルトは'8bit')
    }
    /**
     * 自身のインスタンスを生成
     *
     * @access public
     * @return object new self
     */
    public static function _()
    {
        return new self;
    }
    /**
     * SMTP情報のセッター
     *
     * @access public
     * @param  string $host SMTPのホスト名 Gmail->'smtp.gmail.com'
     * @param  string $usrName ユーザー名 Gmail->'〇〇@gmail.com'
     * @param  string $pass パスワード
     * @param  string $type 通信方法 ssl|tls
     * @param  int    $port ポート番号
     * @return object $this
     */
    public function setSMTP($host, $usrName, $pass, $type = 'tls', $port = 587)
    {
        $this->isSMTP();
        //$this->SMTPDebug = 2;
        $this->SMTPAuth = true;
        $this->Host = $host;
        $this->Username = $usrName;
        $this->Password = $pass;
        $this->SMTPSecure = $type;
        $this->Port = $port;
        return $this;
    }
    /**
     * 差出人のセッター
     *
     * @access public
     * @param  string $from
     * @param  string $name
     * @param  bool   $auto
     * @return object $this
     */
    public function setFrom($from, $name = "", $auto = true)
    {
        parent::setFrom($from, $name, $auto);
        return $this;
    }
    /**
     * 送信先アドレスのセッター
     *
     * @access public
     * @param  string|array $to
     * @param  string       $name
     * @return object       $this
     */
    public function addAddress($to, $name = "")
    {
        // 配列なら$nameを無視してforeachでセット
        // 2次元配列の場合も考えられるのでdistributeAddress()で振り分けている
        if (is_array($to)) {
            foreach ($to as $type => $address) {
                $this->distributeAddress($type, $address);
            }
        } else {
            parent::addAddress($to, $name);
        }
        return $this;
    }
    /**
     * 返信先のセッター
     *
     * @access public
     * @param  string $reply
     * @param  string $name
     * @return object $this
     */
    public function addReplyTo($reply, $name = "")
    {
        parent::addReplyTo($reply, $name);
        return $this;
    }
    /**
     * CCのセッター
     *
     * @access public
     * @param  string $cc
     * @param  string $name
     * @return object $this
     */
    public function addCC($cc, $name = "")
    {
        parent::addCC($cc, $name = "");
        return $this;
    }
    /**
     * BCCのセッター
     *
     * @access public
     * @param  string $cc
     * @param  string $name
     * @return object $this
     */
    public function addBCC($bcc, $name = "")
    {
        parent::addBCC($bcc, $name = "");
        return $this;
    }
    /**
     * ファイルの添付
     *
     * @access public
     * @param  string $path
     * @param  string $name
     * @param  string $encoding File encoding
     * @param  string $type File extension (MIME) type.
     * @param  string $disposition Disposition to use
     * @return object $this
     */
    public function addAttachment($path, $name = "", $encoding = "base64", $type = "", $disposition = "attachment")
    {
        parent::addAttachment($path, $name, $encoding, $type, $disposition);
        return $this;
    }
    /**
     * HTMLメールにするかどうか
     *
     * @access public
     * @param  bool   $isHTML
     * @return object $this
     */
    public function isHTML($isHTML=true)
    {
        parent::isHTML($isHTML);
        return $this;
    }
    /**
     * 件名のセッター
     *
     * @access public
     * @param  string $subject
     * @return object $this
     */
    public function setSubject($subject="")
    {
        $this->Subject = $subject;
        return $this;
    }
    /**
     * 本文のセッター(HTML)
     *
     * @access public
     * @param  string $body
     * @return object $this
     */
    public function setBody($body="")
    {
        $this->Body = $body;
        return $this;
    }
    /**
     * 本文のセッター(non-HTML)
     *
     * @access public
     * @param  string $body
     * @return object $this
     */
    public function setAltBody($body="")
    {
        $this->AltBody = $body;
        return $this;
    }
    /**
     * 文字コードのセッター
     *
     * @access public
     * @param  string $charset
     * @return object $this
     */
    public function setCharSet($charset = "UTF-8")
    {
        $this->CharSet = $charset;
        return $this;
    }
    /**
     * エンコードのセッター
     *
     * @access public
     * @param  string $charset
     * @return object $this
     */
    public function setEncoding($encoding = "base64")
    {
        $this->Encoding = $encoding;
        return $this;
    }
    /**
     * SMTPデバッグモード
     *
     * @access public
     * @param  bool|int $smtpdebug
     * @return object   $this
     */
    public function setSMTPDebug($smtpdebug = false)
    {
        $this->SMTPDebug  = $smtpdebug;
        return $this;
    }
    /**
     * 送信
     *
     * 注:) 送信だけチェーンメソッドの最後に記述する
     * @access public
     */
    public function send()
    {
        if (!parent::send()) {
            trigger_error('Mailer Error: ' . $this->ErrorInfo, E_USER_NOTICE);
        }
    }
    /**
     * 連想配列で渡されたキー(to, cc, bcc)を振り分けるメソッド
     *
     * @param int|string $type
     * @param string     $address
     */
    private function distributeAddress($type, $address)
    {
        if (is_array($address)) {
            foreach ($address as $value) {
                if ($type === 'to') {
                    parent::addAddress($value);
                } elseif ($type === 'cc') {
                    parent::addCC($value);
                } elseif ($type === 'bcc') {
                    parent::addBCC($value);
                }
            }
        } else {
            parent::addAddress($address);
        }
    }
}

最初の呼び出しで日本語を使えるように設定、それ以降はPHPMailerのメソッドをそれぞれラップしているだけです。

見て分かるとおり、さきほど紹介した実例以外で使えるメソッドが複数あります。これらはPHPMailerの仕様にそって利用してください。

基本的にチェーンメソッドで繋いで書けば動作します。

PHPもGitHubも勉強中なので意見ください!

もし、「ここはこうした方がよくない?」とか「こんなバグあるから直して」などの意見がある方は、okutaniのGitHubもしくはTwitter(@okutani_t)までご連絡ください。

特に、GitHubは最近使い始めてよくわかってないので、issueやPull requestなどあればお願いします(僕が対応に手間取ったらごめんなさい)。

PHPでメール機能を実装したい方の参考になれば幸いです。それでは。

参考【脱・日本語JIS】PHPMailerで日本語メールをUTF-8のまま送信する | BLOGRAM

この記事が気に入ったら
いいね ! しよう

Twitter で
LINEで送る
Pocket

okutani (@okutani_t) のヒトコト
PHPMailer便利ですね。自分で言うのもなんですが、NPHPMailer作ってからメール送信で困ることなくなりました。使った人感想くれると嬉しいです( ^ω^)

 - PHP

スポンサーリンク

PC用AdSense

PC用AdSense

Share
  • このエントリーをはてなブックマークに追加
  • Guest

    すみませんが、よくわからないので質問させてください。
    このNPHPMmailerを使うと何が便利なのでしょう?

    PHPMailerは標準で日本語にも対応していますし、文字化けするというのは不適切な文字コード設定が原因です。ソースコードをUTF-8で記述しているなら参考リンクにもある通り

    $mail->CharSet = “UTF-8”;
    $mail->Encoding = “base64”;


    2行をPHPMailerで書くだけで日本語を送信できるはずです。もしソースコードをEUC-JPで書いていたり、日本語JISで送りたいのであれば、
    それなりの文字コード変換が必要になりますが、現在のNPHPMailerはそうした処理に対応できないように見えますので、NPHPMailerを使う
    意味がよくわかりません。

    また、SMTP設定もTLSの578番ポートでハードコーディングされているので、SSLや平文のみに対応したメールサーバでは送信できないように思います。ここは変数にしておくべきではないでしょうか。

    • コメントありがとうございます!うちのブログでこういった技術的なコメントがつくの初めてなのでうれしいです。

      僕自身も、他の参考サイトを見よう見まねで書いたので、きちんとした回答ができるかわからないのですが、僕が意図した目的は次のとおりです。

      ・UTF-8, base64の設定をわざわざ書かなくてよい
      ・ラッパークラスを利用することで、PHPMailerがバージョンアップしたときにPHPMailerを入れ替えるだけで対応できる(PHPMailerに直接コードを記述した場合)
      ・チェーンメソッドを使うことで記述がすっきりする

      この程度の意図なので、わざわざNPHPMailerを使わずともPHPMailerのみで利用してもぜんぜんOKかと思います。UTF-8の記述を書くのが気分的に嫌だったのと、PHPの練習も兼ねて、NPHPMailerを作成してみました。

      SMTPの設定は、第4,5引数にそれぞれ値を渡してあげれば、利用時に変更できるかと思います。記事内で言葉足らずのようでしたら追記します。

      SMTPのデフォルト引数にTLSの578番ポートをわざわざ指定したのは、Gmailの記述を完結にできるようにしたかったためです。

      回答になりましたでしょうか?

  こちらの関連記事もどうぞ

CentOS7にPHP5.6を導入する方法

こんにちは、okutani(@okutani_t)です。本記事ではCentOS7 …

[PHP]はじめてのSmarty導入手順まとめ

こんにちは、okutani(@okutani_t)です。今回はPHPのテンプレー …

MacにHomebrewでPHP, Apache, MySQLを導入する

こんにちは、okutani(@okutani_t)です。MacにはデフォルトでP …

[WordPress]記事内で使える『連載記事一覧』機能をPHPで作ってみた

こんにちは、okutani(@okutani_t)です。ブログを書いていると、連 …

CentOS7+nginxでPHPを利用する方法(PHP-FPM)

こんにちは、okutani(@okutani_t)です。前回の「CentOS7に …

PHPでSlackに「クリームたいやき食べたよ」とメッセージ送るアプリつくった

こんにちは、okutani(@okutani_t)です。先日、前の会社の同期4人 …

[PHP]自作ライブラリをComposer化&Packagistの登録方法

こんにちは、okutani(@okutani_t)です。本記事では、以前作った「 …

[PHP]Composerを導入&はじめてのパッケージインストールまで

こんにちは、okutani(@okutani_t)です。『Composer』とい …

WordPress投稿ページにPHP利用→ショートコードを使おう!

こんにちは、okutani(@okutani_t)です。WordPressではP …

vdeepのトップページへ戻る画像です。風船の形をした島を女の子が掴んでいます。