みろりHP


緑色さんの多目的ブログ
みろりえいちぴー
ごゆるりとおくつろぎあさーせ。
<< 山形石雄『六花の勇者』(M) | main | GIJOE『PHPサイバーテロの技法』 >>
| カテゴリ:プログラミング |
PHP版GCCS





こないだ「以前つくったCoCキャラシート作成ツールをブラウザで動作させてみようとしている」と書いたが、ようやっとひいこら実現させた。機能はもちろんpython版とほぼおなじで、

  • ステータスをランダムに振ってHPやSANを自動計算
  • 入力したデータは整形し別タブで出力

  • という感じだが、python版の機能に加えて

  • 年収欄、キャンペーン・シナリオ欄追加
  • 出力テキストに、どの技能に職業P興味Pを振ったか明示
  • 作成データはデータベースに保存可能
  • 保存データは下部で一覧を閲覧可能
  • 一覧からも整形テキストを出力可能

  • といった機能を追加した。


    いや、データベース機能はもともとつける気はなかったんだ。ただ、PHPとApacheをインストールする際に使用したソフトウェアにMySQLというデータベースも含まれており、「なんじゃこりゃ、でーたべーす?」と調べているうちに面白くなってきたのでついでに組み込んでしまった。どうやらPythonでもデータベースを利用することはできるそうなので、「ついで」で世界が広がり結果オーライといったところか。あと組み込める機能としては、保存データを、テキスト出力するだけでなく編集もできるようにするってところか。実装の構成もわりと容易に考えつく。ただ、まあ、サーバマシンがないからどうせ公開は不可能だしな?
    ズコー、としたところで「公開できないならノウハウを晒せばいいじゃない!」今回はこれを作るのに詰まったところやtipsなどを書くぜ。いやこんなコアなネタをありがたがる人はここの読者にはいないと思うけれどさ、初心者むけの講座が多数並ぶなか、超初心者の「実際にやってみたわ」レポートが存在しているのってそう悪くないとも思うんだよな。

    PHPからDBをいじりたい
    PHP標準クラスのPDOを使え。
    $pdo = new PDO(
        "mysql:dbname=/*使うスキーマの名前*/",
        "接続に使うユーザ名",
        "接続に使うパスワード",
        array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION) # 意味はしらん
        );
    
    で接続をつくる。

    PDOでSELECT, INSERTがしたい
    # SELECT
    $record = $pdo->query("SELECT/*クエリを書く*/")->fetch(PDO::FETCH_ASSOC);
    
    で$recordに array("id"=>1, "name"=>"me") って感じの連想配列が入る。
    $records = $pdo->query("SELECT/*クエリを書く*/")->fetchALL(PDO::FETCH_ASSOC);
    
    で$recordsに array(0=>array("id"=>1, "name"=>"me"), 1=>array("id"=>2, "name"=>"you")) って感じの連想配列が入る。
    # INSERT, UPDATE
    $insert = $pdo->prepare("INSERT/*ここにクエリを書くが、サニタイズのため書き込む値は :id という風にしておく*/");
    $insert->bindValue(":id", /*ここでようやく実際に書き込む値を書く*/, PDO::PARAM_INT);
    $insert->bindValue(":name", /*おなじく*/, PDO::PARAM_STR);
    $insert->execute();
    
    でレコードの挿入。UPDATEはクエリが違うだけで他はINSERTと同じ。

    spanタグに幅を設定したい
    styleにdisplay:inline-block;を入れろ。htmlにはインライン要素とブロック要素があり、幅の指定はブロック要素にしかできない。spanはインライン要素であるため、幅は設定できないことになる。だったらinline-blockでブロック要素にしてしまえという話。

    divを横に並べたい
    並べたいdivのstyleにfloat:left;を追加。並べるのをやめたいところでstyleにclear:both;を追加した空divを置く。

    javascriptとphp間で配列のやり取りをしたい
    javascriptが扱える形にするときはphp側でjson_encode()を使いJSON形式にする。json_decode()で元に戻る。

    javascriptでランダム値を作りたい
    Math.random()を使え。ただこいつがちとくせもので、Pythonのrandom()関数のように引数をとって指定範囲のランダム値を出すというような器用な真似はしてくれない。これ単体では、0から0.999...の乱数を返すのみなので…
    // 0から15のランダム値が欲しければこいつに16を掛け、小数点以下を切り捨てればよい。
    var result = Math.floor(Math.random() * 16);
    // 範囲を指定したければ、最大値から最小値を引いた範囲での乱数を出し、そこに最小値を足せばよい。
    var result = min + Math.floor(Math.random() * (max+1 - min));
    

    javascriptで、htmlから値を取得したり値を突っ込んだりしたい
    document.getElementById().valueかdocument.forms[].elements[].valueを使う。
    <!--html側-->
    <form id="f">
    <input type="text" id="in">
    <output id="out"></output>
    </form>
    // javascript側
    var a = document.getElementById("in").value;
    document.forms["f"].elements["out"].value = a;
    
    この項目はまだ理解しきれていない。そもそも前者のほうではエレメントのidしか求められていないのに、後者ではフォームのidとセットで要求されていやがる。おかしいだろ。まあ別の機会でまた詰まって、詳しく知ることになるだろうさ。

    別ウィンドウにPOST変数を送りたい
    本スクリプトでは、入力されたデータ(並びにそれの計算結果)は連想配列にまとめて別ウィンドウへPOSTで送るが、それは以下のような手順で行っている。これは自分で首をかしげてしまうほど強引なやり口なんだが…。
    <!--html側-->
    <form name="f" method="post">
    <input type="hidden" id="monkey">
    <input type="button" onclick="output();">
    </form>
    // javascript側
    var obj = {};
    function output() {
        document.getElementById("monkey").value = /*回収したデータを連想配列にまとめたもの*/;
        var num = Object.keys(obj).length;
        obj["win" + num] = window.open("", "win" + num);
        document.f.target = "win" + num;
        document.f.submit();
    }
    要するに、javascript側だけでデータをPOST変数に格納して送る方法が思いつかないので、データを一度htmlにぶち込み、javascriptからフォームのsubmitを蹴飛ばし無理矢理POSTで送っているのである。いやjavascriptお前、submitがいじれるのならデータのPOST化くらいやれよと言いたくなる。絶対あると思うんだけどなー。ちなみにobjはなぜ登場しているのかといえば、別ウィンドウが増えるたびにそれらのウィンドウに別々の名前を割り振るためだ。この処理を挟まないと開ける別ウィンドウはひとつだけになってしまう。

    上で言うようなやり方をやったがデータがobjectとかになっちゃってうまくいかんぞ
    オブジェクトを文字列として表示するときはJSON.stringify()を通す。

    ページの一部だけ更新したい
    jQueryをインポートしてajax処理をする。
    $(function() {
        $.ajax({
            url:"gccs.php",
            type:"post",
            data:{
                "a":1 /*リクエスト変数として送りたいデータをオブジェクトで*/
            }
        })
        .done(function(data) {
            /*実行したい内容*/
        });
    });
    
    doneメソッド内の仮引数dataにはサーバのphpから返ってきた内容が入っているので、あとはそれをhtmlのoutputにでもはめ込めばよい。ただし上の方で書いた方法ではテキストデータとして扱われてしまう。htmlデータとして扱ってもらうには次のように書く。
    // こうする
    $("out").html(data);
    // これはダメ
    document.getElementById("out").value = data;
    

    リアルタイムで(計算ボタンなど押さずとも)計算を行う
    これはPython版では「1秒ごとに延々と関数を実行する」ことで実現した機能だったが、「キー入力があったら関数を実行する」ってのがjQueryでちゃっちゃと実装できた。
    $(function() {
        $("#id", "#id2").bind('input', function() {
            // 指定したidに入力があったら実行したい内容
        });
    });
    



    期せずしてPHP、SQL、JavaScriptに一気に触れることになってしまったが、Pythonとの違いにいちいち目をぱちくりさせたりできて結構楽しかったぜ。恥ずかしながら正直に言うと、最初は完全にPython贔屓な態度で「なんじゃこの文法、ヘンなの」とか言っていた。でもいまでは言語ごとに得意分野があるのもわかったし、自然言語と同じく、多言語に触れるほど世界観が広がるのも感じてる。最近ではむしろPythonに目新しさを覚える始末で、

    初期「うっわPHPとかJSって、毎行終わりにセミコロンをつけるのかよ面倒くさ!」
      最近「ヤベ、Pythonコードなのにずっとセミコロンつけてた」

    初期「波括弧つけるの面倒くさ!」
      最近「ヤベ、Pythonコードなのに波括弧つけてた」

    初期「for文に毎回括弧つけるのかよ!!」
      最近「ヤベ、Pythonコードなのに括弧つけてた」

    初期「『$』!!!!???
      最近「ヤベ、Pythonコードなのに『$』つけてた」

    参考:以下のコードは同じ意味。
    # PHP
    function foo() {
        for ($i=0; $i < 10; $i++) { 
            echo $i;
        }
    }
    foo();
    

    # Python
    def foo():
        for i in range(10):
            print(i)
    foo()


    | 緑色 | プログラミング | comments(0) |
    | カテゴリ:- |
    スポンサーサイト
    | スポンサードリンク | - | - |









          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    3031     
    << July 2017 >>
    + みろりHP内検索
    + 閲覧記事
    + 過去記事アーカイブ
    + カテゴリ
    + 年月選択
  • 2017年 07月 (5)
  • 2017年 06月 (4)
  • 2017年 05月 (7)
  • 2017年 04月 (8)
  • 2017年 03月 (7)
  • 2017年 02月 (10)
  • 2017年 01月 (6)
  • 2016年 12月 (8)
  • 2016年 11月 (8)
  • 2016年 10月 (5)
  • 2016年 09月 (5)
  • 2016年 08月 (7)
  • 2016年 07月 (9)
  • 2016年 06月 (6)
  • 2016年 05月 (8)
  • 2016年 04月 (10)
  • 2016年 03月 (10)
  • 2016年 02月 (8)
  • 2016年 01月 (9)
  • 2015年 12月 (9)
  • 2015年 11月 (6)
  • 2015年 10月 (5)
  • 2015年 09月 (4)
  • 2015年 08月 (8)
  • 2015年 07月 (5)
  • 2015年 06月 (3)
  • 2015年 05月 (7)
  • 2015年 04月 (8)
  • 2015年 03月 (12)
  • 2015年 02月 (8)
  • 2015年 01月 (4)
  • 2014年 12月 (5)
  • 2014年 11月 (5)
  • 2014年 10月 (7)
  • 2014年 09月 (4)
  • 2014年 08月 (7)
  • 2014年 07月 (6)
  • 2014年 06月 (4)
  • 2014年 05月 (12)
  • 2014年 04月 (9)
  • 2014年 03月 (6)
  • 2014年 02月 (6)
  • 2014年 01月 (8)
  • 2013年 12月 (7)
  • 2013年 11月 (10)
  • 2013年 10月 (10)
  • 2013年 09月 (9)
  • 2013年 08月 (11)
  • 2013年 07月 (10)
  • 2013年 06月 (9)
  • 2013年 05月 (15)
  • 2013年 04月 (11)
  • 2013年 03月 (5)
  • 2013年 02月 (7)
  • 2013年 01月 (6)
  • 2012年 12月 (9)
  • 2012年 11月 (10)
  • 2012年 10月 (10)
  • 2012年 09月 (4)
  • 2012年 08月 (2)
  • 2012年 07月 (7)
  • 2012年 06月 (13)
  • 2012年 05月 (13)
  • 2012年 04月 (15)
  • 2012年 03月 (4)
  • 2012年 02月 (12)
  • 2012年 01月 (9)
  • 2011年 12月 (5)
  • 2011年 11月 (13)
  • 2011年 10月 (2)
  • 2011年 09月 (2)
  • 2011年 08月 (1)
  • 2011年 06月 (1)
  • 2011年 05月 (4)
  • 2011年 04月 (10)
  • 2011年 03月 (8)
  • 2011年 02月 (11)
  • 2011年 01月 (14)
  • 2010年 12月 (14)
  • 2010年 11月 (17)
  • 2010年 10月 (17)
  • 2010年 09月 (19)
  • 2010年 08月 (22)
  • 2010年 07月 (18)
  • 2010年 06月 (16)
  • 2010年 05月 (19)
  • 2010年 04月 (15)
  • 2010年 03月 (22)
  • 2010年 02月 (18)
  • 2010年 01月 (18)
  • 2009年 06月 (2)
  • 2009年 04月 (1)
  • 2007年 12月 (10)
  • 2007年 11月 (7)
  • 2007年 10月 (9)
  • 2007年 09月 (4)
  • 2007年 07月 (5)
  • 2007年 06月 (11)
  • 2007年 05月 (6)
  • 2007年 04月 (4)
  • 2006年 01月 (20)
  • + ブックマーク
    + 最近のコメント
    + アクセスカウンター
    全体(since 2010.02.03.)
    今日… 昨日…