Cocos2d-xでhttp通信を使い、PHPでのMySQLとの連携をやってみる

#最初に
この記事を作ろうと思ったきっかけは自分でPHPでの通信をやろうとした時に、
参考サイトを見て作ろうとしたがあまりにも資料が少なくそしてサンプルを打ち込んでも出来なくて
なおかつ情報が古いと思い作成に至りました。筆者も他の方のありがたいサイトを見て作成さして頂いたので
私もそういう存在になれたら良いと思います。
#使用するソフト、ライブラリ
XAMPP(Apach,MySQL)
PHP編集ソフト（メモ帳で代用可能、筆者はhtmlなども兼ねているのでBrackets
cocos2d-x(筆者はCocosをDLしてGUIからプロジェクトの立ち上げなどを行っています
PicoJson(ライブラリ、情報の送受信に適したデータに変換
#環境構築
まず最初にNetwork関連のことが出来るソフトをまとめたXAMPPというものをDLします。
なぜならXAMPPの中にあるApachはhttp通信のために、MySQLはDBとして使うのでネットワークをするため必須です。
こちらを参考に
http://ponk.jp/php/basic/install
MySQLを使用するときはMySQLもStartして、Adminをクリックして作業をおこなってください。

次はPHP編集ソフト、取り敢えずの試しならメモ帳で大丈夫かも？保存時に.phpとUTF-8に変換する必要があるかもしれない
cocos2d-x公式サイトからどうぞ、COCOSの方をDLするとGUIでプロジェクトの作成や削除が可能
PicoJson　こちらから↓
https://github.com/kazuho/picojson
#参考サイト
http://qiita.com/hkomo746/items/214d0482b6090c0a3ce0
#PHPの保存場所
こちらを参考に~
http://ponk.jp/php/basic/kihon
#送信時のコード　※は補足解説参照
```cpp:HelloWorldScene.cpp
auto request = new cocos2d::network::HttpRequest();
request->setUrl("http://xxxx/test.php");     //ここについては後で解説します　※1
request->setRequestType(cocos2d::network::HttpRequest::Type::POST);
//ここは送受信時の関数なため送信だけしたい場合などはなくててよい
request->setResponseCallback(CC_CALLBACK_2(LoginScene::callbackHttpRequest, this));
request->setTag("Login");
//自分の送りたい名前 MySQLの設定をしていないと日本語は使えないので注意 ※2
m_account_name="test";
m_password="test";

picojson::object obj;
obj.insert(make_pair("account_name", picojson::value(m_account_name)));
obj.insert(make_pair("password", picojson::value(m_password)));

picojson::value val(obj);
std::string json = val.serialize();
request->setRequestData(json.c_str(), json.length());

auto httpClient = cocos2d::network::HttpClient::getInstance();
httpClient->enableCookies(nullptr);
httpClient->send(request);
```
```cpp:HelloWorldScene.h
#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__
#include "network/HttpClient.h"　//このヘッダーをincludeするのを忘れずに！
#include <vector>　//こちらもjsonを使うときのmake_pirのために必要です！
#include "cocos2d.h"
#include "ui/CocosGUI.h"
#pragma execution_character_set("utf-8") //cocosで日本語を使う
class HelloWorldScene : public cocos2d::Scene
{
public:
	// there's no 'id' in cpp, so we recommend returning the class instance pointer
	static cocos2d::Scene* createScene();

	// Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone
	virtual bool init();

	// implement the "static create()" method manually
	CREATE_FUNC(HelloWorldScene);
private:
	//名前格納用変数
	std::string m_account_name;
	//パスワード格納用変数
	std::string m_password;
	//受信用関数
	void callbackHttpRequest(cocos2d::network::HttpClient *sender, cocos2d::network::HttpResponse *response);
};

#endif // __HELLOWORLD_SCENE_H__
```
```php:test.php
<?php

$postData = file_get_contents("php://input");
//Jsonの受け取り
$inputData = json_decode(stripcslashes($postData));

//データベースに接続　第三引数は自分が作成したMySQLの構造の名前 ※3
$db=mysqli_connect('localhost','root','','自分が作成したデータベース名') or die(mysqli_connect_error());

//受け取るデータ
//account_name
//password

//アカウントデータとパスワードを挿入  ※4
$sql=sprintf('INSERT INTO 自分の設定したテーブル名 SET account_name="%s",password="%s"',mysql_real_escape_string($inputData->account_name),mysql_real_escape_string($inputData->password));
//上のSQL文を実行
mysqli_query($db,$sql) or die(mysqli_error($db));
//文字コードの設定
header( "Content-Type: application/json; charset=utf-8" );
//受信用のコードのために返信
echo json_encode($inputData);
```
```cpp:HelloWorld.cpp
void LoginScene::callbackHttpRequest(cocos2d::network::HttpClient *sender, cocos2d::network::HttpResponse *response)
{
    if (response->isSucceed()) {

        // json.
        std::vector<char> *buffer = response->getResponseData();
        const char *data = reinterpret_cast<char *>(&(buffer->front()));
        picojson::value v;
        std::string error;
        picojson::parse(v, data, data + strlen(data), &error);
        CCASSERT(error.empty(), error.c_str());

        picojson::object &obj = v.get<picojson::object>();
        std::string &name = obj["account_name"].get<std::string>();
        std::string &password = obj["password"].get<std::string>();
        log("account_name:%s password:%s", name.c_str(), password.c_str());
    }
    else {
        CCLOG("HttpRequest failed");
    }
}
```
#解説補足
※1 
こちらのxxxxはサーバーのipアドレスを入力を入力する所ですが、
筆者は勉強目的でやっていたのでlocalhost/test.php、もしくはコマンドプロンプトでipconfigと入力してもらい、
IPV4の部分を入力して貰えれば同じLAN内でならネットワーク通信が出来ると思われます。
同じ記事ですがこちらを
http://ponk.jp/php/basic/kihon
しかしこの記事の設定を行った場合保存場所が変わり
"http://localhost/php/test.php"
こうなると思います。
※2
標準のMySQLの設定ではUTF-8の設定にされていないので参考にしたサイトを貼っておきますので日本語を使いたいときはそちらをどうぞ
http://qiita.com/guzuri/items/643c1311224e8d482278
※3
こちらはまずMySQLのNewをクリックして頂き、データベースを作成し、その名前を入力していただければokです
※4
作成したデーターベースをクリックすると名前、カラム数と出るので名前をつけて(ここを入力),カラム数を2つにして頂き、
そのあとの２つの項目の名前とデータ型などを決めるよう出てくるので、一つの名前をaccount_name データ型はstring
もう一つの名前はpasswordにデータ型はstringで作成するようお願いします。
#結果
このコードを適切に打つことによってCocosを実行するたびに
MySQLのデータベースに名前とパスワードが登録されます。
確認のためには更新が必要なのでCocosを実行→F5でページを更新してください。
logに出てきた名前とパスワードが登録されていれば成功です。
#応用編
```php:loginCheck.php
<?php

$postData = file_get_contents("php://input");
$inputData = json_decode(stripcslashes($postData));

//データベースに接続
$db=mysqli_connect('localhost','root','','自分が作成したデータベース名') or die(mysqli_connect_error());

//受け取るデータ
//account_name
//password
//flag

//打った名前とパスワードが重複してしていたらcntに重複した数をカウント
$check=sprintf('SELECT COUNT(*) AS cnt FROM 自身が作成したテーブル名 WHERE name="%s" AND password="%s"',mysql_real_escape_string($inputData->account_name),mysql_real_escape_string(sha1($inputData->password)));
//データベースをセット
$que=mysqli_query($db,$check);
//phpを実行して変数で受け取り
$table= mysqli_fetch_assoc($que);

//変数にチェックした数が入っているので重複してなかったら追加
if($table['cnt']==0)
{
    //1を入れたら存在しているか
    $inputData->flag="1";
    //挿入
    $sql=sprintf('INSERT INTO 自身が作成したテーブル名　SET name="%s",password="%s"',mysql_real_escape_string($inputData->account_name),mysql_real_escape_string(sha1($inputData->password)));
    mysqli_query($db,$sql) or die(mysqli_error($db));
}
else
{
    $inputData->flag="0";
}

header( "Content-Type: application/json; charset=utf-8" );
echo json_encode($inputData);

```
#応用編結果
アカウント登録時に重複チェックを行ってくれて同じものがあったら登録しない、なかったらする
flagはココス側で受け取るときにその数字で登録しましたor 同じ名前とパスワードで登録されています。
と出るようにCocos側でソースをCallback内で書きました。
#最後に
色々拙い部分が多かったりXAMPPやPicoJsonなどの解説はほったらかしにしてしまい非常に申し訳ないです。
筆者はなるべくコメントなどを見るよう心がけますので
少しでも分からない部分があったり、
ここがおかしい更には分からないからXAMPPなどの設定もQiitaで書いて～などのコメントがありましたら、
記事を修正又は記事の作成まで行わして頂きますのでコメントおねがいします。