エモンのブログ(スマホアプリ作成日記) -24ページ目

エモンのブログ(スマホアプリ作成日記)

エモンのブログです。

GooglePlayとAppStoreにアプリをリリースしてます。
「詰将棋パラダイス」4500問無料で公開。
「みんなのしょうぎ」投票型の将棋対局。いずれもソーシャルアプリなので、ソーシャルゲーム作成に興味があるかたは是非ご覧ください。

1. はじめに

SQLインジェクション対策としてプリペアドステートメントを使いました。
CakePHPで実行することを前提として使い方を確認していきましょう。
まずSQLを発行するときにユーザからの入力が不正である場合、下手をするとこちらが意図をしているSQL以外のSQLが発行されてしまう可能性があります。
パラメータにシングルクオートなど入れて工夫を凝らすとそうなってしまいます。
解決方法としてこちらが意図するSQLを先に決定してしまい、パラメータだけ入れ替える形が良いですね。
それがプリペアドステートメントですキリ。


2. PHP上のプリペアドステートメント

「?」がプレースホルダといわれるもので後々queryの第2引数の配列で置換されます。
$qry = '';
$qry .= 'select * from answer_managers where user_id = ? and work_id = ? ';
$params = array($userId, $workId);
$result = $this->query($qry, $params);
return $result[0];

へへ、なんつーかCakePHPとぜんぜん関係ないじゃないか・・・。


3. MySQL上のプリペアドステートメント

なぜか更新時にプリペアステートメントが失敗してしまったのでPHPではなくMySQLで行ってみた。
平のSQLではこんな感じ
PREPARE [クエリ名] from '[プレースホルダ付SQL]'
SET @[変数 = '[置換変数]', ・・・
EXECUTE [クエリ名] USING @[変数1], @[変数2], @[変数3]

これをPHP上で実行するには以下を参照のこと
$qry = "PREPARE ANSWER_REGIST FROM 'UPDATE answer_managers SET ";
$qry .= "name=? ";
$qry .= "WHERE ";
$qry .= "user_id=? AND work_id=? ' ";
$this->query($qry);
$this->query("SET @c1 = '".$name."', @c2 = '".$uid."', @c3 = '".$workId."' ");
$this->query("EXECUTE ANSWER_REGIST USING @c1, @c2, @c3 " );


デコポニテの魔女」の提供でこのブログは書かれております。
デコポニテの魔女はAndroid端末用簡易右スクロールシューティングゲームです。
Technology By: Adobe AIR & CakePHP
1.リクエストパラメータ内の日本語

アカウント管理するときやコメントをする際に日本語をサーバへ送ったりするが、
もちろんURLエンコードする必要がある。インポートする必要があるのが以下の2つ
import flash.utils.escapeMultiByte;
import flash.utils.unescapeMultiByte;


リクエストパラメータにて日本語を含める際
unescapeMultiByte(日本語のString);

という風にエンコードできる。※別のやり方としてescapeとunescapeがあるが、一般的なエンコードじゃないので却下。


PHP側では送られてきた変数に対し、やりたいならSanitizeをしたあと、
※AIRだからhtmlspecialcharsは不要。あと mysql_escape_stringは適宜。
$name = $this->params['form']['name'];
urldecode(name);


これでAIRで入力した文字列がPHPでも使えるようになる。


2.twitterへのポスト

次にtwitterへのポストについて考えてみる。
※OAuthを使うのではなく、別ウィンドウにポスト文字列が勝手に入っているアレだ。
ニコニコ動画やpixivでやってますな。
あれを実現するにはNavigateURL時のURLに工夫が必要になる。
https://twitter.com/intent/tweet?related=[適当にアプリIDなど]&source=tweetbutton&text=[URLエンコードしたポスト内容]

ポスト内容の中にURLを混ぜたい場合はそのURL自体をエンコードする。
※urlパラメータはなぜだかiOSだと利かなかった
+%23tag+http%3A%2F%2Fwww.google.com

ハッシュタグ#を入れる場合は%23のあとにタグをいれ「+」を入れてスペースで区切ろう。

出来上がりのURLが最終的にこんな形になればOKだ。
※クリックしてもいいけどポストしちゃだめだぜ
https://twitter.com/intent/tweet?related=kukilabo&source=tweetbutton&text=%28%E8%A9%B0%E5%B0%86%E6%A3%8B%29%E3%83%81%E3%83%AB%E3%83%8E%E3%81%95%E3%82%93%E3%81%8C%E4%BD%9C%E5%93%81No13%E3%82%92%E8%A7%A3%E3%81%8D%E3%81%BE%E3%81%97%E3%81%9F%E3%80%82%E3%82%AF%E3%83%AA%E3%82%A2%E3%83%A9%E3%83%B3%E3%82%AD%E3%83%B3%E3%82%B0%EF%BC%9A1936%E4%BD%8D%20%E3%82%BF%E3%82%A4%E3%83%A0%E3%83%A9%E3%83%B3%E3%82%AD%E3%83%B3%E3%82%B0%EF%BC%9A2%E4%BD%8D%20%20+%23tumesuma+http%3A%2F%2Fkukilabo.sakura.ne.jp%2Fgames%2Fintroductions%2Findex%2F2


※追記:iPodで確認したらURLがさらにエンコードされてしまった。iOSだとポスト内容の部分はURLエンコードする必要はないかも。
前回からの続き。AIRとPHPを連携すれば前回のアカウント管理が可能になってきます。


1.やりたいこと

AIRから通信を開始し、サーバ上の情報を取得してそのまま表示する。


2.通信に必要なもの

AIRからサーバ上の情報を取得する場合、以下リクエストと呼ぶことにします。
リクエストをサーバに投げるとき必要になるのはそのサーバのURLになります。
また、サーバの情報を取得するにしてもAIRから条件を指定したりする場合もあるでしょう。
その場合リクエストパラメータをURLにくっつける必要があります。
http://www.example.com/?userId=100
こんな感じですね。
こうするとサーバにuserIdとその中に100が入っている変数が送られます。
これと同じことをAIR上で(※つまりAS3.0で)やってみましょう


2.ASの記述

//通信先URL
var url:String = URL
//サーバ応答の変数型指定(URL変数を指定)※サーバから出力形式をa=0&b=0といったURL変数に指定している
var loader:URLLoader;
loader.dataFormat = URLLoaderDataFormat.VARIABLES;
//応答リスナー※サーバから値を受け取ったときに走らせる関数を定義(onComplete)
addEventListener(Event.COMPLETE, onComplete, false, 0, true);
//URL設定※ランダム文字列を追加しているのはキャッシュ削除のため
var req:URLRequest = new URLRequest(url+"?"+Math.random(10000));
//メソッド指定(POST):GETとPOSTがあるが、POSTを選択する。どっちでもいいが、どちらかを選択する。
req.method = URLRequestMethod.POST;
//リクエストパラメータをセット。ここではuserId=100の部分
var param:URLVariables = new URLVariables();
param.userId = 100;
req.data = params;
//通信開始
loader.load(req);


これで通信開始をします。
サーバ上での出力を取得し、onComplete関数に戻ってきます。


3.PHPの記述

指定したURLのサーバ上にPHPを置いておき、URL変数をplain/textで出力をするようにしておきます。
本来は受け取った変数($_POST["userId"])を条件にしてDB接続して・・・などと夢を広げますが、ここでは省略します。
$_POST["userId"]はさっきいれた100が入ってます。
自分はCakePHPを使っているのでControllerのアクションメソッドで以下のように書きます。
$this->autoRender = false;  //HTMLレンダリングさせずにプレーンテキストを表示させるため。
$this->params['form']['userId']; //リクエストパラメータの受け取り
echo 'd=0&name=dekoponite'; //※なぜか最初の変数をAs3.0で認識しないらしいのでd=0のダミーを置いておく

Cakeを使わない場合は
<?php 
header("Content-type: text/plain ");
echo 'd=0&name=dekoponite';

たぶんこんな感じ。


4.ASにてサーバからの出力情報を受け取り

さっきonCompleteをリスナーとして登録したので、その関数を作ります。
public function onComplete(evt:Event) {
//サーバ応答を取得
var res:URLVariables = evt.target.data;
trace(res['name']); //※ さっきPHPでechoした”dekoponite”が表示される
}



以上でAIRとPHPの連携の説明を終わります。
今回の記事を参考すれば前回のログインが可能になるわけです。

なお、これを利用して作ったのが例によってコレ。
デコポニテの魔女