Angular から PHP に JSON データを Post する

Angular から PHP に JSON データを Post する時に、PHP 側で `$_POST` で受け取る処理を検索したら[自分の記事がヒットした](https://qiita.com/koronpo/items/1f93f4dfbd75ecf9cb95)けど、お前 POST 処理しているけど何も値送信してねーじゃねーか、となったのでメモ。単純に `$_POST` では受け取れないのでちょっと一手間必要。

# ポイント
- HttpHeaders の Content-Type を [application/x-www-form-urlencoded](https://developer.mozilla.org/ja/docs/Web/HTTP/Methods/POST) に
- 送信データをまるっと1つの変数に入れる
- PHP で受け取った値を json_decode する

# ソース

## GlobalService(global.service.ts) 作成

Service として作成しなくても良いけど使い勝手良いので作成。ポイントは `HttpHeaders` 値。

```ts
import { Injectable }                   from '@angular/core';
import { HttpClient, HttpHeaders }      from '@angular/common/http';
import { timeout, catchError}           from 'rxjs/operators';
import { Observable, throwError}        from 'rxjs';

const HTTP_OPTIONS = {
  headers: new HttpHeaders({
    'Content-Type':  'application/x-www-form-urlencoded; charset=UTF-8'
  })
};

@Injectable({
  providedIn: 'root'
})


export class GlobalService {

  /**
   * コンストラクタ
   * @param {HttpClient} _http
   */
  constructor(
    private _http: HttpClient
  ) { }

  /**
   * httpポスト処理
   * @param {string} _postUrl - 送信URL
   * @param {any} _trans_data - 送信データ（デフォルト空）
   * @return {Observable<any>} http.post処理のレスポンス
   */
  public http(_postUrl: string, _trans_data: any = ''): Observable<any> {
    let ret: Observable<any>;
    let postUrl: string;
    postUrl = _postUrl;
    ret = this._http.post(postUrl, _trans_data, HTTP_OPTIONS)
    .pipe(
      timeout(5000),
      catchError(this.handleError())
    );
    return ret;
  }

  /**
   * Observable のエラーを返却します
   * @param 無し
   * @return {Observable<any>}
   */
  private handleError(): any {
    return (error: any): Observable<any> => {
      const ret = {
        'status': error.status
        , 'data': error.statusText + '/' + error.url
      };
      return throwError(ret);
    };
  }

}

```

## TopComponent(top.component.ts) 作成

POST 処理を行うページ。ポスト処理は画面ボタンのクリックにて行う想定。ポイントは送信 JSON 値を1つの変数に入れて送るところ。

```ts
import { Component, OnInit }      from '@angular/core';
import { GlobalService }          from '../../services/global.service';

@Component({
  selector: 'app-top',
  templateUrl: './top.component.html',
  styleUrls: ['./top.component.scss']
})

export class TopComponent implements OnInit {

  /**
   * コンストラクタ
   * @param {GlobalService} globalService
   */
  constructor(
    public gs: GlobalService
  ) {}

  ngOnInit() {}


  // クリック処理で POST 処理実施
  public clickTest() {
    let temp;
    temp = {
      'test': 'テストデータ'
    };

    const body = 'data=' + JSON.stringify(temp);  // <- 送信 JSON 値を data 変数に入れて送る

    this.gs.http('/test.php', body).subscribe(
      res => {
        console.log('success: ' + JSON.stringify(res));
      },
      error => {
        console.log('error: ' + JSON.stringify(error));
      }
    );
  }

}
```

## PHP 処理

受け取る PHP は以下の感じ。json_decode で連想配列として取り扱える。

```php
<?
$post = json_decode($_POST['data'], true);

$retArray = array(
  'rType'=> 'success'
  , 'message'=> $post['test'] // <- 送信されてきた「テストデータ」という文字列がこれで取得出来る
);

header('Content-type: application/json');
echo json_encode($retArray, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
```

以上で作業一式。

# 参考
[Post JSON from angular 2 to php](https://stackoverflow.com/questions/35325816/post-json-from-angular-2-to-php)