ReactとPHPで簡単なメールフォームを自作する

Reactでサイト制作を行なっているのですが、お問い合わせフォームが必要になったためPHPと組み合わせてメールフォームを作成してみました。

まずはReact側から

import React from 'react';
require('es6-promise').polyfill();
require('isomorphic-fetch');

class Mail extends React.Component { 
  constructor() {
    super();
    this.state = {
      data: {
        name: '',
        email: '',
        title: '',
        comment: ''
      }
    }
    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleChange(event) {
    var data = this.state.data;

    switch (event.target.name) {
      case 'name':
        data.name = event.target.value;
        break;
      case 'email':
        data.email = event.target.value;
        break;
      case 'title':
        data.title = event.target.value;
        break;
      case 'comment':
        data.comment = event.target.value;
        break;
    }

    this.setState({
      data: data
    });
  }

  handleSubmit() {
    fetch('*******/mail.php', {
      method: "POST",
      mode: "no-cors",
      headers: {
        "Content-Type": "application/json"
      },
      body: JSON.stringify({
        name: this.state.data.name,
        email: this.state.data.email,
        title: this.state.data.title,
        comment: this.state.data.comment
      })
    }).then(res_ => {
        if (res_.status >= 400) {
            throw new Error("Bad response from server");
        }
      
        res_.json().then(data_ => {
            console.log(data_);
        });
    });
  }

  render() {
 return (
 <form action="javascript:void(0)" onSubmit={this.handleSubmit}>
 <label htmlFor="name">お名前</label>
 <input type="text" name="name" value={this.state.name} onChange={this.handleChange} />
 <label htmlFor="email">メールアドレス</label>
 <input type="email" name="email" value={this.state.email} onChange={this.handleChange} />
 <label htmlFor="title">題名</label>
 <input type="text" name="title" value={this.state.title} onChange={this.handleChange} />
 <label htmlFor="comment">お問い合わせ内容</label>
 <input type="text" name="comment" value={this.state.comment} onChange={this.handleChange} />
 <button type="submit">送信</button>
 </form>
 );
  }
};

いつもの事ながらフォームの値はstateで管理しています。

今回はメールを送信するにあたってPHPファイルへPOSTリクエストを送る必要があったため、isomorphic-fetchを利用しています。

fetchの第一引数に後述するPHPファイルを置いてある場所を指定してください。

今回はJSON形式で送信するため、bodyはJSON.stringifyでJSON形式に変え、headerも指定しています。

 

次にメールを送信するPHPファイルです

mb_language("Japanese");
mb_internal_encoding("UTF-8");
$params = json_decode(file_get_contents('php://input'), true);
$name = $params['name'];
$email = $params['email'];
$title = $params['title'];
$comment = $params['comment'];
$message = '[お名前]'."\n".$name."\n";
$message .= '[email]'."\n".$email."\n";
$message .= '[コメント]'."\n".$comment."\n\n\n";
$header = 'From: '.$email."\r\n";
$header .= 'Reply-To: '.$email."\r\n";
$to = 'hogehoge@example.com';
if(mb_send_mail($to, $title, $message, $header)){
  echo "メールを送信しました";
} else {
  echo "メールの送信に失敗しました";
};

mb_send_mail()を利用してメールを送信しています。

パラメータは、(送信先のアドレス, 件名, 本文, ヘッダオプション)です。

注意しなければならなかったのは、3行目の記述を追加する事です。

$_POSTで取得できると思っていましたが、JSONを受け取る時は この記述が必要になります。

php://input は読み込み専用のストリームで、 リクエストの body 部から生のデータを読み込むことができます。

これをfile_get_contents()で文字列に読み込み、デコードしています。これで連想配列のように取得できるようになりました。

このPHPファイルを適当なサーバーにのせ、先ほどのReactのフォームからPOSTを飛ばしてあげる事でメールを送信することができます。

今回はバリデーションも何もしていないので、実際に運用する時はセキュリティにも気をつけて使用してください。

 

今回は以下の記事を参考にさせていただきました。ありがとうございます。

「isomorphic-fetchでPOSTリクエストを送る」

「Reactで複数のinputを扱うフォームを実装する」