目次

中堅SE向け研修

PHPによるサーバへの接続(続)

JSON形式でない接続

AngularJSの$httpサービスは、デフォルトの動作でPOSTやGETメソッドの送信データをJSON形式に変換してくれる。

これは、サーバサイドのスクリプトもNode.js等のJavaScriptで書かれている場合は便利な機能だが、PHPで受けるには不便である。

そこで、送信するデータを下記のコードで通常のx-www-form-urlencode形式に変換する。(要jQuery)

  $httpProvider.defaults.headers.post['Content-Type'] ='application/x-www-form-urlencoded';
  $httpProvider.defaults.transformRequest = function (data) {
    if (data === undefined)
      return data;
    return $.param(data);
  };

このコードは、app.jsのapp.config()の中に書くことで、起動時に自動的に設定される。

作成したコード

registMember.php

<?php
/* 新規メンバーを登録する
 * nm : 氏名
 * ge : 性別
 * ma : メールアドレス
 * bt : 血液型
 */
  try{
    $pdo=new PDO("mysql:host=mysql514.db.sakura.ne.jp;".
                "dbname=forcreate_XXXXXXXX;".
                "charset=utf8",
                "forcreate","XXXXXXXX");
    $q="insert into member (name,gender,mail,bloodtype)".
      " values (:name,:gender,:mail,:bloodtype);";
    $s=$pdo->prepare($q);
    $sa=array(":name"=>$_POST['nm'],
             ":gender"=>$_POST['ge'],
             ":mail"=>$_POST['ma'],
             ":bloodtype"=>$_POST['bt']);
    $s->execute($sa);
    $q="select * from member order by id desc limit 1;";
    $s=$pdo->prepare($q);
    $s->execute();
    print json_encode($s->fetchAll());
  }
  catch(PDOException $e){
    print json_encode(array("msg"=>$e->getMessage()));
  }
?>

modifyMember.php

<?php
/* 指定したIDのメンバーを更新する
 * id : ID
 * nm : 氏名
 * ge : 性別
 * ma : メールアドレス
 * bt : 血液型
 */
  try{
    $pdo=new PDO("mysql:host=mysql514.db.sakura.ne.jp;".
                "dbname=forcreate_XXXXXXXX;".
                "charset=utf8",
                "forcreate","XXXXXXXX");
    $q="update member set ".
      "name=:name,".
      "gender=:gender,".
      "mail=:mail,".
      "bloodtype=:bloodtype,".
      "modified=now() where id=:id;";
    $s=$pdo->prepare($q);
    $sa=array(":id"=>$_POST['id'],
              ":name"=>$_POST['nm'],
              ":gender"=>$_POST['ge'],
              ":mail"=>$_POST['ma'],
              ":bloodtype"=>$_POST['bt']);
    $s->execute($sa);
    //print json_encode(array("result"=>$s->rowCount()));
    $q="select * from member where id=:id;";
    $s=$pdo->prepare($q);
    $sa=array(":id"=>$_POST['id']);
    $s->execute($sa);
    print json_encode($s->fetchAll());
  }
  catch(PDOException $e){
    print json_encode(array("msg"=>$e->getMessage()));
  }
?>

deleteMember.php

<?php
/* 指定したIDのメンバーを削除する
 * id : ID
 */
  try{
    $pdo=new PDO("mysql:host=mysql514.db.sakura.ne.jp;".
                "dbname=forcreate_XXXXXXXX;".
                "charset=utf8",
                "forcreate","XXXXXXXX");
    $q="delete from member where id=:id;";
    $s=$pdo->prepare($q);
    $sa=array(":id"=>$_POST['id']);
    $s->execute($sa);
    print json_encode(array("result"=>"ok"));
  }
  catch(PDOException $e){
    print json_encode(array("msg"=>$e->getMessage()));
  }
?>

app.js

(function () {
  var app = angular.module("MemberManager", ['ngRoute']);

  // ルーティング
  app.config(function ($routeProvider,$httpProvider) {
    $routeProvider
      .when('/', {
        templateUrl: 'list.html',
        controller: 'ListController'
      })
      .when('/regist', {
        templateUrl: 'regist.html',
        controller: 'RegistController'
      })
      .when('/modify/:num', {
        templateUrl: 'modify.html',
        controller: 'ModifyController'
      })
      .otherwise({
        redirectTo: '/'
      });
    $httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
    $httpProvider.defaults.transformRequest = function (data) {
      if (data === undefined)
        return data;
      return $.param(data);
    };
  });

  // 初期化
  app.run(function (MemberService) {
    MemberService.load();
    //MemberService.regist("john", "male", "john@aaaa.jp", "A");
    //MemberService.regist("paul", "male", "paul@bbbb.uk", "B");
    //MemberService.regist("marry", "female", "marry@cccc.jp", "O");
  });
}());

services.js

(function () {
  var app = angular.module("MemberManager");

  // 会員クラス
  // id : シリアル番号
  // name : 氏名
  // gender : 性別
  // mail : メールアドレス
  // bloodtype : 血液型
  // modified : 修正日時
  var Member = function (id, nm, ge, ma, bt, mo) {
    this.id = id;
    this.name = nm;
    this.gender = ge;
    this.mail = ma;
    this.bloodtype = bt;
    this.modified = mo;
  };

  // 会員サービス
  app.factory("MemberService", function ($http) {
    var ms = {} // サービスの実体
    ms.s_max = 0; // 会員番号の最大値
    ms.members = []; // 会員リスト
    ms.Member = Member; // 会員コンストラクタ

    // 新規会員の登録
    ms.regist = function (nm, ge, ma, bt) {
      $http({
          method: 'post',
          url: 'http://seminar-senior.jeez.jp/fuchida/MemberManager/php/registMember.php',
          data: {
            nm: nm,
            ge: ge,
            ma: ma,
            bt: bt
          }
        })
        .success(function (data, status, headers, config) {
          console.log(data);
          var d = data[0];
          ms.members.push(new ms.Member(
            d.id,
            d.name,
            d.gender,
            d.mail,
            d.bloodtype,
            new Date(d.modified)));
        })
        .error(function (data, status, headers, config) {
          alert("Error:" + data.msg);
        });
    };

    // 会員情報の修正
    // num : ms.membersリストの中の番号
    // mem : 修正後の会員の情報
    ms.modify = function (num, mem) {
      $http({
          method: 'post',
          url: 'http://seminar-senior.jeez.jp/fuchida/MemberManager/php/modifyMember.php',
          data: {
            id: mem.id,
            nm: mem.name,
            ge: mem.gender,
            ma: mem.mail,
            bt: mem.bloodtype
          }
        })
        .success(function (data, status, headers, config) {
          console.log(data);
          var d = data[0];
          var m = ms.members[num];
          m.name = d.name;
          m.gender = d.gender;
          m.mail = d.mail;
          m.bloodtype = d.bloodtype;
          m.modified = new Date(d.modified);
        })
        .error(function (data, status, headers, config) {
          alert("Error:" + data.msg);
        });
    }

    // 会員情報の削除
    ms.delete = function (num) {
      var mem=ms.members[num];
      $http({
          method: 'post',
          url: 'http://seminar-senior.jeez.jp/fuchida/MemberManager/php/deleteMember.php',
          data: {
            id: mem.id
          }
        })
        .success(function (data, status, headers, config) {
          console.log(data);
          ms.members.splice(num, 1);
        })
        .error(function (data, status, headers, config) {
          alert("Error:" + data.msg);
        });
    };

    // サーバーからデータをロードする
    ms.load = function () {
      $http({
          method: 'post',
          url: 'http://seminar-senior.jeez.jp/fuchida/MemberManager/php/getMember.php'
        })
        .success(function (data, status, headers, config) {
          console.log(data);
          for (var i in data) {
            ms.members.push(new ms.Member(data[i].id,
              data[i].name,
              data[i].gender,
              data[i].mail,
              data[i].bloodtype,
              new Date(data[i].modified)));
          }
        })
        .error(function (data, status, headers, config) {
          alert("MemberServce: load error");
        });
    };

    return ms;
  });
}());

list.html

性別と血液型でフィルタリングできるようにした。

<p>
  <button class="btn btn-default" ng-click="changeUrl('regist')">
    新規登録
  </button>
</p>
<form class="form-inline">
  性別:
  <select class="form-control" ng-model="gender_filter">
    <option value='b'>両方</option>
    <option value='m'>男</option>
    <option value='f'>女</option>
    <option value=''>なし</option>
  </select>
  血液型:
  <select class="form-control" ng-model="bloodtype_filter">
    <option value='all'>すべて</option>
    <option value='A'>A型</option>
    <option value='B'>B型</option>
    <option value='AB'>AB型</option>
    <option value='O'>O型</option>
  </select>
</form>
<table class="table">
  <thead>
    <tr>
      <th>ID</th>
      <th>氏名</th>
      <th>性別</th>
      <th>メール</th>
      <th>血液型</th>
      <th>更新日</th>
    </tr>
  </thead>
  <tr ng-repeat="m in members
      |genderSelect:gender_filter
      |bloodtypeSelect:bloodtype_filter">
    <td>{{m.id}}</td>
    <td><a href="#/modify/{{$index}}">{{m.name}}</a></td>
    <td>{{m.gender|gender}}</td>
    <td>{{m.mail}}</td>
    <td>{{m.bloodtype}}</td>
    <td>{{m.modified | date:'yyyy年MM月dd日 HH時mm分ss秒'}}</td>
  </tr>
</table>

filters.js

(function () {
  var app = angular.module("MemberManager");

  // 性別フィルタ
  // 'male'なら'男'、'female'なら'女'を返す
  app.filter("gender", function () {
    return function (value) {
      if (value == 'male') return '男';
      if (value == 'female') return '女';
      return '?';
    };
  });

  // 性別選別フィルタ
  // 指定した性別だけを通す
  // m : 男性
  // f : 女性
  // b : 両方
  // それ以外 : 何も通さない
  app.filter('genderSelect', function () {
    return function (values, flag) {
      if (!angular.isArray(values)) return values;
      if (flag == 'b') return values;
      var newValues = [];
      angular.forEach(values, function (v) {
        if ((flag == 'm' && v.gender == 'male') ||
          (flag == 'f' && v.gender == 'female'))
          newValues.push(v);
      });
      return newValues;
    }
  });

  // 血液型選別フィルタ
  // 指定した性別だけを通す
  // all : すべて
  // A : A型
  // B : B型
  // AB: AB型
  // O : O型
  // それ以外 : 何も通さない
  app.filter('bloodtypeSelect', function () {
    return function (values, flag) {
      if (!angular.isArray(values)) return values;
      if (flag == 'all') return values;
      var newValues = [];
      angular.forEach(values, function (v) {
        if (flag==v.bloodtype)
          newValues.push(v);
      });
      return newValues;
    }
  });

  // 性別転換
  app.filter("toggleGender", function (MemberService) {
    return function (values) {
      if (!angular.isArray(values)) return values;
      var newValues = [];
      angular.forEach(values, function (v) {
        var m = new MemberService.Member();
        newValues.push(m);
        m.id = v.id;
        m.name = v.name;
        m.gender = v.gender;
        m.mail = v.mail;
        m.bloodtype = v.bloodtype;
        m.modified = v.modified;
        if (m.gender == 'male')
          m.gender = 'female';
        else
          m.gender = 'male';
      });
      return newValues;
    };
  });
}());

テスト環境の構築

AngularJSではJasmineとKarmaが標準のテストフレームワークである。

まずは環境を構築しよう。

Node.jsのインストール

jasmineのインストール

karmaのインストール


トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS