【macOS×XAMPP】sendmail.iniなんてないけど、どうやってPHPでメール送るの？？(Gmail経由)

##環境

OS　→　macOS Big Sur ver 11.1
サーバ/DB　→　XAMPP 7.4.13-0
エディタ　→　Visual Studio Code
メール　→　 Gmail

##ターゲット(この記事を読むべき人)##

- PHPを用いてローカル環境からメールを送りたいけど、送れずに悩んでいる人
- sendmailというメールエージェントが見当たらず先に進めない人
- macOSの記事が少なく自分に合う情報が見つからず困っている人

ペルソナは私と同じような初学者向けの記事となっているので、現役のエンジニアの方々は「こんなところでお前つまづいたのか」と笑いながら読み進めていただければ...

### 自分が陥った状況

ローカル環境にあるPHPアプリケーションからメールを自分のGmailに飛ばそうとした結果、飛ばせない。
メールの飛ばし方をググるとたくさん記事が出てくる。
参照してみると、まずphp.iniをいじってポート番号や宛先を変える。その後どうやらsendmail.phpというファイルをいじるとのこと。

しかし、このsendmail.iniがどうやらmacOS上を漁っても出てこない...
そこからsendmailの設定ファイルであるsendmail.iniの実態を掴むまで数日かかり苦労した。

##sendmail.iniはmacOSのどこにある？

結論から申すと、
**sendmailはmacOSにはない。**

もう少し調べてみると、どうやら違うメールサーバがmacには標準搭載されているらしい。
その名前は、**「postfix」**である。

###そもそもメールサーバってなんぞや

sendmailやpostfixの実態を掴むためにまずはメール送信の仕組みについて話していく。

メールの送受信というものは、**SMTP**と**POP**(IMOP)というプロトコルを用いて行われる通信のことである。
プロトコルというのは、通信の手段を明確に定めた規格である。
サーバとクライアントでお互い扱うデータの種類や通信の手法をあらかじめ統一しておくためのルールみたいなもの。
メールでのやりとりをするときは常にsmtpやpop.imopが使われている。

メール配送の様子を簡易化した図がこちら。
![mail-1.png.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1064956/4949d456-de54-f648-28de-bcf78ff1c1b8.jpeg)

引用元: [【図解】初心者にも分かるメールの仕組み～SMTP/POP/IMAPの違い, リレーの構成, 用語について～](https://milestone-of-se.nesuke.com/nw-basic/grasp-nw/mail/)


>**MTA(Mail Transfer Agent)**
メールを配送するためのプログラムで、ホスト間でのメールの配送や配送されてきたメールを受け取る機能をもっています。代表的なMTPは、**sendmail,qmail,Postfix**などがあります。

>MDA(Mail Delivery Agent)
MTAがメールを受け取ると、各ユーザのメールボックスにメールを配信する機能を持っています。代表的なMDAは、mail.local,procmail,qmail-localなどがあります。

>MUA(Mail User Agent)
主にユーザがメールを読み書きし、送受信する機能を持っています。メーラーとも言われ、アドレス帳やメールの振り分け機能を持っているアプリケーションが多く存在ます。また、インターネットメールの仕様に合わせたコード変換などを自動的に行います。代表的なMDAは、Becky!,Outlook Express,Eudora,Muleなどがあります。

>引用元: [SMTP配送の仕組みとsendmail](http://linuxexpert.ne.jp/modules/pukiwiki/index.php?cmd=read&page=MailServer%2FSMTP%C7%DB%C1%F7%A4%CE%BB%C5%C1%C8%A4%DF%A4%C8sendmail&word=MailServer)

厳密にいうと、メールサーバ内にあるMTAがsendmailやpostfixである。
phpを動かすapacheサーバにメール配送機能があるのではなく、メールサーバ内にあるエージェントが相手のメールサーバに配送しているという認識だけ頭に入れて欲しい。

今回は
``postfix → gmailサーバ　→　相手のメールサーバ``
というgmail経由でのリレー転送方法を解説していく。


##転送方法

postfixの役割とメール送信の流れについて把握したところで、以下のアクションプランを提示する。今回はローカル環境での送信テストなので、必要最小限の手順のみ紹介。

1. php.iniを編集しpostfixに対してコネクションをとる
2. postfixの設定ファイルを開き宛先を記述する
3. saslの設定

###前提条件

ファイル編集はvimというエディタで行う。
vimの使い方がわからない人は、こちらの記事で基礎動作を把握しておいてほしい。
https://qiita.com/okamos/items/c97970ab34ff55ff3167

###1 php.iniを編集する

この部分を編集。smtpのポート番号とホストを設定。

```
[mail function]
; For Win32 only.
; http://php.net/smtp
SMTP=localhost /* ← ここをlocalhostに */
; http://php.net/smtp-port
smtp_port=25 /* ←ここを25に */
```

###2 postfixの設定

ここからはpostfixをいじる。
まずターミナルを使いpostfixディレクトリに移動。パスは以下の通り

```
cd /etc/postfix/
```
root権限を用いてmain.cfをvimで開く

```
sudo vi main.cf
```
main.cfにて以下の場所を探す

```
#relayhost = $mydomain
#relayhost = [gateway.my.domain]
#relayhost = [mailserver.isp.tld]
#relayhost = uucphost
#relayhost = [an.ip.add.ress]
```
直下にrelayhostの宛先と設定を記述し保存( :wq )

```
relayhost=[smtp.gmail.com]:587
smtp_sasl_auth_enable=yes
smtp_sasl_password_maps=hash:/etc/postfix/sasl_passwd
smtp_use_tls=yes
smtp_tls_security_level=encrypt
tls_random_source=dev:/dev/urandom
smtp_sasl_security_options = noanonymous
smtp_always_send_ehlo = yes
smtp_sasl_mechanism_filter = plain

```
relayhostに今回gmailを使うので、gmailのポート番号を使用する。
[gmailをsmtpリレーとして使うためのポート番号の調べ方](https://office-hack.com/gmail/smtp/)

saslというライブラリを使うためにその情報も記述している。
saslは、異なるプラットフォームのユーザ認証を手助けするライブラリ。
アプリケーション毎にリレーサーバに対してのアクセス方法が変わってきてしまうため、saslを用いてユーザ認証を共通化している。

###3 saslの設定

saslのユーザ認証方法の流れ

```
gmail認証するためのパスワードを格納したファイルを作成
↓
ファイルのパーミッションを設定
↓
ファイルをDB化する
```

まずはgmail認証データをpostfixディレクトリ内にsasl_passwdというファイル名で作成。
(ここのファイル名は、main.cfに追記したsmtp_sasl_password_mapsのファイル名と一致させる)

```
sudo vi sasl_passwd
```


sasl_passwdには以下のフォーマットで必要な情報を記述

```
[smtp.gmail.com]:587   GMAILメールアドレス:パスワード
```

保存したら、sasl_passwdファイルのパーミッションを指定

```
sudo chmod go-rx sasl_passwd
```
最後にsasl_passwdをハッシュマップ データベースファイル化する。

```
sudo postmap hash:/etc/postfix/sasl_passwd
```

これでsaslの設定は終了。
最後にpostfixを起動、または再起動させます。

```
起動
sudo postfix start

再起動
sudo postfix reload
```


##まとめ

macOSに関する情報がwindowsに比べて少なかったので、自分がローカル環境でメールを送信できた手法を紹介した。
「phpで簡単にメールを送れる」という情報をよく目にするが、根底にあるLinuxなどOSに関する知識やプロトコルを理解していないとテスト環境の構築は難しいと感じた。