LoginSignup
18
22

More than 5 years have passed since last update.

AngularJSでWebAPI(PHP)連携 POST編

Last updated at Posted at 2015-05-23

AngularJSで$http.postすると、いわゆる普通にPOSTがされない。そのため、

$name = $_POST['name']

というお馴染みの形式で受け取れない。

標準では、
$postdata = file_get_contents("php://input");
$request = json_decode($postdata);
$name = $request->name;
という感じで受け取れる(後述)

この形式で受け取るためには、

  • Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'

でなければいけない(UTF-8である必要はないけど)。また、値がPOSTパラメータ文字列形式でなくてはならない。

といった感じ。これを実現する必要がある。

前提条件

  • PHPでWebAPIを作る。
  • APIはnameとemailを受け取ってそのままjsonで返す。

API

とりあえずこんな感じ。

<?php

    $name = "default";
    $email = "default@test.com";

    if(isset($_POST['name'])) $name = $_POST['name'];
    if(isset($_POST['email'])) $email = $_POST['email'];

    $res = [];
    $res['name'] = $name;
    $res['email'] = $email;

    header("Content-type: application/json");
    echo json_encode($res);

フロント

こんな感じ。$http.postのデータ形式をJSONではなく、POSTパラメータ文字列に。オプションとしてContent-typeを指定している。

<!doctype html>
<html land="ja" ng-app="myApp">
<head>
<meta charset="utf-8">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
<script>

//app
var app = angular.module('myApp',[]);

//controller
app.controller('myCtrl',function($scope,$http){

    $http.post('http://localhost/res.php',encodeURI("name=hoge&email=foo@test.com"),{

        headers: {'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'}

    })
    .success(function(response){

        //response
        $scope.name = response.name;
        $scope.email = response.email;
    });

});
</script>
</head>
<body>
<div ng-controller="myCtrl">
{{name}}<br>
{{email}}
</div>
</body>
</script>

応用

受け渡すデータ形式はJSONで指定したいということはあると思います。その場合は、下記のようにjqueryの$.param()関数を利用して変換できる。transformRequestで変換する方法もあるようですが、覚えられないのでこれで。

<!doctype html>
<html land="ja" ng-app="myApp">
<head>
<meta charset="utf-8">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<script>

//app
var app = angular.module('myApp',[]);

//controller
app.controller('myCtrl',function($scope,$http){

    $http.post('http://localhost/res.php',$.param({"name":"hoge","email":"hoge@hoge.com"}),{

        headers: {'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'},

    })
    .success(function(response){

        //response
        $scope.name = response.name;
        $scope.email = response.email;

    });

});
</script>
</head>
<body>
<div ng-controller="myCtrl">
{{name}}<br>
{{email}}
</div>
</body>
</script>

変換用の関数を定義し、transformRequestの値として渡すと変換されるみたい。

さらに応用(FormDataを使う)

FormDataを使うと記述が汎用的でよい。Fileも送れる(カスタムディレクティブを作る必要はある)。
Content-typeはmultipart/form-dataになる。

<!doctype html>
<html lang="ja">
<head>
<meta charset="utf-8">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
<script src="js/app.js"></script>
<script>
//app
var app = angular.module('myApp',[]);
//controller
app.controller('hogeCtrl',function($scope,$http){

    //init
    $scope.name = "";
    $scope.email = "";

    //onclick
    $scope.btnClick = function(){

        //formdata
        var fd = new FormData();
        fd.append('name',$scope.name);
        fd.append('email',$scope.email);

        $http.post('res.php',fd,{
            transformRequest: null,
            headers: {'Content-type':undefined}
        })
        .success(function(res){
            $scope.response = res;
        });
    }

});
</script>
</head>
<body>
<div ng-app="myApp" ng-controller="hogeCtrl">

name:<input type="text" name="name" ng-model="name"><br>
email:<input type="text" name="email" ng-model="email"><br>
<button ng-click="btnClick()">upload</button>

<p>{{name}}</p>
<p>{{response}}</p>

</div>
</body>
</html>

AngularJSの標準形式での受け取り

郷に入れば郷に従えの精神で、Angular標準のPOSTの受け取り方も。

API

素のPHP

$_POSTではなく、file_get_contents()を利用する。file_get_contentsって何でもとれるのね。

<?php

    $name = "default";
    $email = "default@test.com";

    $postdata = file_get_contents("php://input");

    $request = json_decode($postdata);

    $name = $request->name;
    $email = $request->email;

    $res = [];
    $res['name'] = $name;
    $res['email'] = $email;

    header("Content-type: application/json");
    echo json_encode($res);

Laravel

LaravelだとResponseファサードで取れる。

Route::post('hoge',function(){

    //get content
    $request = \Request::instance();
    $content = $request->getContent();

    //decode
    $obj = json_decode($content);

    //get params
    $name = $obj->name;
    $email = $obj->email;

    //param to array
    $res = [];
    $res['name'] = $name;
    $res['email'] = $email;

    //json response
    return Response::json($res);
});

フロント

シンプルで素敵。Angularを利用するなら、この形式でPHP側を開発した方がいいでしょう。

<!doctype html>
<html land="ja" ng-app="myApp">
<head>
<meta charset="utf-8">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
<script>

//app
var app = angular.module('myApp',[]);

//controller
app.controller('myCtrl',function($scope,$http){

    $http.post('http://localhost/res.php',
    {
        "name":"hoge",
        "email":"hoge@hoge.com"
    })
    .success(function(response){

        //response
        $scope.name = response.name;
        $scope.email = response.email;

    });

});
</script>
</head>
<body>
<div ng-controller="myCtrl">
{{name}}<br>
{{email}}
</div>
</body>
</script>
18
22
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18
22