【PHP】Ajaxで非同期通信を行う方法。

#Ajaxを用いて画面遷移しないお問合わせフォームを作る
今回はWebサイトでよく見られる画面遷移しないお問い合わせフォームを作っていきます。
##コード
まずhtmlはただのお問い合わせフォームです。
特に変わりはありません。

```index.html
        <form class="form-area" action="mail.php" method="post">
          <div class="form">
            <span id="msg"></span>
            <div class="input">
              <input class="input-name" name="name" type="text" placeholder="お名前">
            </div>
            
            <div class="input">
              <input class="email" name="email" type="email" placeholder="email">
            </div>
            
            <div class="input">
              <input class="subject" name="subject" type="text" placeholder="件名">
            </div>

            <textarea class="text" name="message" id="" cols="30" rows="10" placeholder="お問い合わせ内容"></textarea>

            <button id="button" class="send" type="submit" name="send">Send Mail</button>

          </div>
        </form>
```
そして、Ajaxです。
Send mailボタンが押されたら、お問い合わせ入力フォームの各値をmail.phpにpost送信で送ります。

```main.js
$(function(){
    // ===========================================
    // Ajaxを利用したお問い合せ
    // ===========================================
        $('.send').on('click', function(e){
        e.preventDefault();

        // var serialize = $('form').serialize();
        $.ajax({
                url: 'mail.php',
                type:'POST',
                dataType: 'json',
                data: {
                    name: $('.input-name').val(),
                    email: $('.email').val(),
                    subject: $('.subject').val(),
                    message: $('.message').val()
                },
            }).done(function(data){
                // alert('成功');
                console.log(data.text);
               
            }).fail(function(msg, XMLHttpRequest, textStatus, errorThrown){
                alert(msg);
                console.log(XMLHttpRequest.status);
                console.log(textStatus);
                console.log(errorThrown);
            });
        }
        });
});
```
最後はmail.phpでバリデーションを行い、main.jsに返します。

```mail.php
<?php

    require('function.php');
    header('Content-Type: application/json; charset=utf-8');

    // ===================================================================
    // メール送信
    // もしPOST送信されていたら
    if(!empty($_POST)){

      $to = 'sax.guiter@icloud.com';
      $name = $_POST['name'];
      $email = $_POST['email'];
      $subject = $_POST['subject'];
      $message = $_POST['message'];
      
      // 各値に対しvalidationを行う
      validRequired($name, 'name');
      validRequired($subject, 'subject');
      validRequired($message, 'message');
      validemail($email, 'email');
      
      $msg = array();
      $array = array();
        // 全てのvalidationをクリアしたら
        if(empty($err_msg)){
          debug('バリデーションOK');
      
          mb_language('japanese');
          mb_internal_encoding('UTF-8');
      
          $result = mb_send_mail($to, $subject, $message, $name, $email);
      
          if($result){
            unset($_POST);
            $msg["text"] = "メールが送信されました";
            echo json_encode($msg);

            debug('メールを送信します');
          } else {
            $msg = '送信に失敗しました';
            debug('メールの送信に失敗しました');
          }
      
        } else {
        $msg["text"] = '全て入力してください';
        debug('validationに引っかかています');
       }
      }
      debug('画面表示処理終了 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<');

?>
```


##解説
まず、main.jsから説明します。
考え方はこう。
***「何をどこにどんな風にして送信し、どんな形で返してもらうのか」です。***
それを決めているのがこの部分です。

```main.js
         $.ajax({
                url: 'mail.php',
                type:'POST',
                dataType: 'json',
                data: {
                    name: $('.input-name').val(),
                    email: $('.email').val(),
                    subject: $('.subject').val(),
                    message: $('.message').val()
                },
```
なので***「dataをmail.phpにpost送信し、json形式で返してください」***
といった感じです。
下の

```main.js

}).done(function(data){
                alert('成功');
                console.log(data.text);

}).fail(function(msg, XMLHttpRequest, textStatus, errorThrown){
                alert('失敗');
                console.log(XMLHttpRequest.status);
                console.log(textStatus);
                console.log(errorThrown);
            });
```
これは単純に通信が成功したときの処理と失敗したときの処理を書いています。
.failの引数について説明します。
**XMLHttpRequestt**・・・XMLHttpRequestに定義されている様々なメソッドを使用することができます。
つまりconsole.log(XMLHttpRequest.status)というのはXMLHttpRequestの中にあるstatusメソッドを使用しています。console.log(XMLHttpRequest.status)ちなみにこれはHTTPリクエストのステータスが取得できます。
200とか404ってやつですね。
**textStatus**・・・タイムアウト、パースエラーなどのエラー情報が取得できます。
**errorThrown**・・・例外のエラー情報を取得します。

そして、mail.phpです。
いたって普通のバリデーションを行いますが必要なのは
・header()
・json_encode()
この二つです。

まず ***header('Content-Type: application/json; charset=utf-8');***はレスポンスするファイル形式をtext/htmlからapplication/json;に変更するためのものです。

次に***json_encode();***はphpの値をjson形式にするためのものです。

main.jsでdataType: 'json'と記述しました。
「ファイルはjason形式で返してね。」というものです。
仮にheader()をつけず、text/htmlでレスポンスしても読み取ってはくれるのですが、中身はencodeされてるのでjson形式で記述されています。

つまりどういうことか言うと、header()をつけないと言うことはjson形式で記述されているファイルの拡張子を.htmlで保存するみたいなものなんですね。

なのでheader()をつけ、期待されているファイル形式で返してあげましょう。

話は戻りまして、バリデーションが終わったらその結果をmain.jsで受け取るために**echo json_encode()**で呼び出しましょう。

そして、main.jsの.done or .failの引数で受け取り、consoleなりalertなり表示させるだけです。

##まとめ
・Ajaxでの記述
・header()関数
・json_encode()関数
を学びました。

画面遷移をどうするかと言うのはUI/UXにも関わってくる所なので適材適所に使っていきたいなと思います。