SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

IoTをかじってみよう

IoTをかじってみよう(3)
~センサーのデータをWebサーバーに送付するmbedアプリケーションを作成する

PHPによるWebアプリケーションの開発

 前節までにMySQLとnginxとPHP関連モジュールが稼働するコンテナイメージができたので、次はPHPアプリケーションが稼働するコンテナイメージを作成します。最終的にIBM Containers上で稼働させるコンテナです。

 ホストOS上で適当なディレクトリを作成します。

$ mkdir ~/iotkaji_docker2

 作成したディレクトリにDockerfileとリリース用のソースファイルを置きます。

 先ほどのsusumutani3/iotkaji:v3をベースにしますが、稼働確認のために使用したtest.phpはサーバー情報が見えてしまい望ましくありません。IBM Containers上で稼働させるコンテナイメージからは削除します。

 まずDockerfileは下記のとおりです。

Dockerfile(~/iotkaji_docker2/Dockerfile)
# Dockerfile for IoTかじってみよう PHPアプリケーション
FROM susumutani3/iotkaji:v3

MAINTAINER Susumu Taniguchi

# test.phpを削除します。
RUN rm /usr/share/nginx/html/test.php
ADD writedb.php /usr/share/nginx/html/writedb.php
ADD readdb.php /usr/share/nginx/html/readdb.php

EXPOSE 80
CMD ["/usr/local/bin/init.sh"]

 PHPアプリケーションのwritedb.phpとreaddb.phpもいっしょに置きます。

 冒頭で述べたように今回のレシピでは、mbedからHTTPのPOSTリクエストでデバイスID(deviceid)、温度(temperature)、メモ(memo)の3項目を受信して、既に作成したデータベースのテーブルへINSERTするためのPHPのアプリケーションであるwritedb.phpと、同じデータベースからデータを読み込んで表示するためのPHPのアプリケーションであるreaddb.phpを作成します。それぞれソースコードを下記に記載します。

 ちょっと長いように見えますが、PHPのおさらいとして主要な部分の内容を確認していきます。

 <?phpから?>までの間にはさまれた部分がPHPアプリケーションです。

  • (1)PHPでは、POSTリクエストで送信されたデータを$_POST['名称']で参照します。その際に、htmlspecialchars()関数を使用して特殊文字をHTMLエンティティへ変換しておくことで、後続の処理で特殊文字による不具合が発生することを防ぎます。
  • (2)MySQLの拡張モジュールであるmysqliクラスを使用してMySQLサーバーへ接続します。前節までで作成したデータベースとユーザーを使用します。
  • (3)MySQLサーバーへの接続で失敗した場合は終了します。
  • (4)テーブルへデータをINSERTするSQLは、mysqli::prepare()メソッドを使用してプリペアードステートメントとして用意しておきます。このとき変数の部分にはプレースホルダ「?」を使います。
  • (5)mysqli::bind_param()メソッドを使用して、プリペアードステートメントのSQLとhtmlspecialchars()で処理済みの変数をバインドします。
  • (6)続いてmysqli::execute()メソッドでSQLを実行します。
  • (7)最後にデータベースとの接続をクローズします。

 なお、//はコメントアウトです。このほかにもシェル型の#やC型の/* */のコメントアウトが使用できます。

writedb.php(~/iotkaji_docker2/writedb.php)
<?php
    // (1)POSTされたデータ$_POST['名称']の文字列中の特殊文字を、HTMLエンティティに変換します。
    $deviceID = htmlspecialchars($_POST['deviceid'],ENT_QUOTES);       // deviceidとして送られたデータを取り込みます。
    $temperature = htmlspecialchars($_POST['temperature'],ENT_QUOTES); // temperatureとして送られたデータを取り込みます。
    $memo= htmlspecialchars($_POST['memo'],ENT_QUOTES);                // memoとして送られたデータを取り込みます。

    if(!is_numeric($temperature)) $temperature=0.0; // $temperatureが数字であることの確認、違う場合は0.0にします。

    try{
        // (2)mysqliクラスを使用してMySQLサーバーへ接続します。
        $conn = new mysqli('localhost','user_iot','pass_iot','SampleIotDB'); // 前節までで作成したデータベースとユーザーを使用します。

        // (3)MySQLサーバーへの接続で失敗した場合の処理を記載します。
        if($conn->connect_errno){
            echo 'connection failure';
            die('error message: ' . $conn->connect_errno);
        }

        // (4)テーブルへデータをINSERTするSQLをプリペアードステートメントとして用意します。
        // 「?」の部分はプレースホルダです。
        if(!($stmt = $conn->prepare("INSERT INTO sample1_tbl(deviceid,temperature,memo) VALUES(?,?,?)"))){
            echo 'sqlstatement prepare failure';
            printf("error message: %s<br>",$mysqli->errno);
        }

        // (5)プリペアードステートメントのSQLに変数をバインドします。
        if(!$stmt->bind_param("sds",$deviceID,$temperature,$memo)){ // "sds"は、変数がstring,double,stringであることを意味します。
            echo 'SQL bind failure';
            printf("error message: %s<br>",$mysqli->errno);
        }

        // (6)SQLを実行します。
        if(!$stmt->execute()){
            echo 'SQL execute failure';
            printf("error message: %s<br>",$mysqli->errno);
        }
    }finally{
        // (7)MySQLサーバーへの接続を終了します。   
        $conn->close();    
    }
?>

 データベースからデータを読み出して表示するreaddb.phpは次の通りです。

  • (1)writedb.phpと同様にMySQLの拡張モジュールであるmysqliクラスを使用してMySQLサーバーへ接続します。
  • (2)MySQLサーバーへの接続で失敗した場合は終了します。
  • (3)テーブルへデータをSELECTするSQLを用意します。
  • (4)SQLを実行します。クエリの結果をmysqli_resultクラスの変数$resultにセットします。
  • (5)mysqli_resultクラスのmysqli_fetch_assocメソッドで、クエリの結果の行を連想配列で取得して表示します。
  • (6)最後にデータベースとの接続をクローズします。
readdb.php(~/iotkaji_docker2/readdb.php)
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
<title>IoTをかじってみよう3章readdb</title>
</head>
<body>
<?php
    try{
        // (1)mysqliクラスを使用してMySQLサーバーへ接続します。
        $conn = new mysqli('localhost','user_iot','pass_iot','SampleIotDB'); // 前節までで作成したデータベースとユーザーを使用します。

        // (2)MySQLサーバーへの接続で失敗した場合の処理を記載します。
        if($conn->connect_errno){
            echo 'connection failure';
            die('error message: ' . $conn->connect_errno);
        }

        // (3)テーブルへデータをSELECTするSQLを用意します。
        $sql1 = 'SELECT deviceid,temperature,memo,datetime FROM sample1_tbl';

        // (4)SQLを実行します。
        $result = $conn->query($sql1);
        
        printf("result is<br>\n");
        // (5)クエリの結果の行を連想配列で取得して表示します。
        while( $row = $result->fetch_assoc() ){
            printf("%s %f %s %s<br>\n", $row['deviceid'],$row['temperature'],$row['memo'],$row['datetime']);
        }
    }finally{
        // (6)MySQLサーバーへの接続を終了します。   
        $conn->close();
    }
?>
</body>
</html>

 作成したDockerfileを使用して起動シェルの含まれたイメージを作成します。

$ sudo docker build -t susumutani3/iotkaji:v4 ~/iotkaji_docker2

 イメージが作成できていることを確認します。

$ sudo docker images

 作成したイメージのコンテナを実行します。

$ sudo docker run --name testing -it -p 80:80 susumutani3/iotkaji:v4

 ここまでできたらサーバー側は完了ですが、念のためテストしておきましょう。

curlの準備

 今後のデバッグのために、ここでホストOS側にcurlというツールを導入しておきます。これは、URLを指定するとHTTPやHTTPSなどのプロトコルでデータを転送してくれるツールです。後々mbedからのPOST送信した結果が正しいかどうかを調べる可能性があるため用意します。

$ sudo apt-get install curl

 それではホストOS側からcurlコマンドでデータをPOSTしてみます。複数回実行してかまいません。

$ curl --data "deviceid=MBED1111&temperature=12.345&memo=test" http://localhost/writedb.php

 このコマンドでwritedb.phpにPOSTできます。先ほどと同じくホストOS側のブラウザでhttp://localhost/readdb.phpにアクセスしても確認できますが、w3mでも次のコマンドで確認できます。

$ w3m http://localhost/readdb.php
図16 w3mでの稼働確認結果
図16 w3mでの稼働確認結果

 PHPアプリケーションの機能の確認ができました。

次のページ
mbedからの接続確認

この記事は参考になりましたか?

IoTをかじってみよう連載記事一覧

もっと読む

この記事の著者

谷口 督(日本アイ・ビー・エム株式会社)(タニグチ ススム)

2000年問題対応の時期にIT業界に入り、それ以来UNIX系のインフラ構築を担当。最近の関心事は、そろそろ出てきそうな画期的なテクノロジー探しや世の中が良くなるためのもの作りです。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/9162 2016/01/27 14:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー