まだプログラマーですが何か?

プログラマーネタとアスリートネタ中心。たまに作成したウェブサービス関連の話も http://twitter.com/dotnsf

タグ:php

以前からずっと悩んでいたのが、PHP と IBM DB2 の相性の悪さ(苦笑)でした。

知らない方が多いと思うので補足すると、PHP からデータベースにアクセスする場合には PDO(PHP Data Object) の拡張モジュールが必要になります。更に PDO に加えてデータベースの種類毎(例えば MySQL とか PostgreSQL とか)に接続するための拡張モジュールをシステムに導入しておく必要があります。

CentOS での例を書いておくと、例えば MySQL や PostgreSQL を使う場合はそれぞれ以下のようにして、これらのモジュールをインストールすることができます(PDO 拡張モジュールごとインストールできます):
(MySQL の場合)
# yum install php-mysql
(PostgreSQL の場合)
# yum install php-postgresql

さて IBM DB2 のケースです。普通に "yum install php-db2" などと入力しても「何それ?」みたいな扱いになります(苦笑)。
# yum install php-db2
  :
  :
パッケージ php-db2 は利用できません。
エラー: 何もしません

ではどこから拡張モジュールをインストールするのか・・・ と思って調べてみたのですが、かなりハードル高そうです:
http://php.net/manual/ja/ibm-db2.installation.php


↑リンク先を読んでいただくとわかりますが、自分でヘッダファイルやライブラリファイルを用意して、ビルドしろ、ということになっています。ということは DB2 のインストールモジュールが必要になるわけで・・・ 普通に PHP から使いたいだけなのですが、クラウドの DBaaS として使うにはかなりハードルが高めに設定されているように見えますね。。


一方で IBM Bluemix 環境であれば、このハードルはぐっと下がります。なにしろ「用意されたビルドパックを使うだけ」です。

前提として、IBM Bluemix 上に dashDB のインスタンスを1つ作成し、以下のようなテーブル(names)を定義しておきます:
2016111401
↑ID(int) と NAME(varchar(20)) だけのテーブル定義

2016111402
↑3つのレコードを入力済み


この dashDB インスタンスを、IBM Bluemix 上に作成した PHP ランタイムからバインドしてアクセスする、というアプリケーションを作ります:
2016111401



ビルドパックはこちらにあるものをそのまま利用します:
https://github.com/ibmdb/db2heroku-buildpack-php

ソースコード(index.php)はこんな感じで用意します(ホスト名やユーザー名、パスワードなどは Bluemix の接続情報を参照して取得します):
<html>
<head>
<title>DB2</title>
</head>
<body>
<table border="1">
<tr><th>ID</th><th>NAME</th></tr>
<?php
$host = "xxxxx.services.dal.bluemix.net"; # DB2(dashDB) のホスト名
$port = 50000; # ポート番号
$db = "BLUDB"; # データベース名
$username = "(username)"; # ユーザー名
$password = "(password)"; # パスワード

$conn_str = "DRIVER={IBM DB2 ODBC DRIVER};DATABASE=" . $db . ";HOSTNAME=" . $host . ";PORT=" . $port . ";PROTOCOL=TCPIP;UID=" . $username . ";PWD=" . $password . ";";
$conn = db2_connect( $conn_str, $username, $password );
if( $conn ){
  $sql = "SELECT * FROM \"names\"";
  $stmt = db2_prepare( $conn, $sql );
  $result = db2_execute( $stmt );
  if( $result ){
    while( $row = db2_fetch_array( $stmt )){
?>
<tr><td><?php print_r($row[0]); ?></td><td><?php print_r($row[1]); ?></td></tr>
<?php
    }
  }else{
    $error = db2_stmt_error( $stmt );
    $errormsg = db2_stmt_errormsg( $stmt );
?>
<tr><td><?php print_r($error); ?></td><td><?php print_r($errormsg); ?></td></tr>
<?php } } ?> </table> </body> </html>

PHP 内で dashDB のインスタンスに接続して SQL を実行し、全レコードを取り出して表示する、という内容になっています。PHP としては非常にシンプルですが、"db2_" で始まる拡張関数が数か所使われており、DB2 用のコードになっていることがわかると思います。

こいつを cf コマンドでプッシュします。その際に -b オプションで上記のビルドパックを指定します:
# cf push (アプリ名) -b https://github.com/ibmdb/db2heroku-buildpack-php

この方法で作成したアプリケーションにアクセスすると、PHP の IBM DB2 拡張が読み込まれて実行され、期待通りの結果が表示されます:
2016111403


PHPer の皆さん、IBM Bluemix と dashDB であれば面倒な手続きなく PHP からも使えます。是非アプリを作ってみましょう!


なお、PHP の IBM DB2 拡張機能については公式ドキュメントが存在しているので、関数リファレンスも含めて詳しくはこちらを参照ください:
http://php.net/manual/ja/book.ibm-db2.php


業務に関係して、ちょっとした画像アップローダーが欲しくなったので、IBM Bluemix でも動くようなものを作って一般化したものを公開します:
https://github.com/dotnsf/ImgUploader


PHP + MySQL + HTTP サーバー環境で動きます。Bluemix であれば PHP ランタイムClearDB試験提供の MySQL サービスを組み合わせた環境を想定しています:
2016061000


中身は非常にシンプルで、画像をアップロードして一覧で表示したり、プレビューしたり、というものです。画像データは BLOB 型にして MySQL 内に格納しているので、MySQL のバックアップを取ると画像データがバックアップされます。ここにアップロードした画像は URL でアクセスできるようになります。

アップロードに際しては PHP 設定の制約などを受けます。Bluemix 環境であれば最大 2MB です。PHP の設定を変更するなどしてください。必要に応じて認証を付けて運用してください。

その他、シンプルなので普通に使えると思っていますが、詳しくは GitHub の README を参照ください。


かなり以前に Bluemix 環境で phpMyAdmin を動かす場合の流れを紹介したことがあります:
BlueMix 上で PHP アプリを動かす


が、ここで紹介している内容は Bluemix がまだベータ版だった 2014 年頃のもので、今となっては内容が古くなってしまいました。改めて 2016/Feb/08 時点での手順を紹介します。

まず、何はともあれ Bluemix 環境内に PHP ランタイムを作成し、MySQL サービスをバインドします。MySQL サービスはオープンソース版ClearDB 版の2つの選択肢がありますが、どちらでも構いません。以下はオープンソース版を使っているものとして説明しています:
2016020803


PHP プロジェクトのメニューから「環境変数」を選択し、バインドされた MySQL サービスに関する接続情報を確認します。この中の credentials 内から hostname, port, name(データベース名), username, password の内容を確認してメモしておきます(後で使います):
2016020804


次に phpMyAdmin のページ上部から最新版の phpMyAdmin をダウンロードします。この記事を書いている 2016/Feb/08 時点での最新バージョンは 4.5.4.1 であり、ダウンロードファイルの名前は phpMyAdmin-4.5.4.1-all-languages.zip でした。以下、この環境を前提として記述しますが、最新バージョンが変更になった場合は適宜読み替えてください:
2016020801


ダウンロードした zip ファイルを展開して、適当なフォルダに格納します。以下の例では C:\tmp\phpmyadmin\ というフォルダの中に phpMyAdmin というサブフォルダ名で展開しています:
2016020802


展開結果のファイルの中から config.sample.inc.php ファイルを config.inc.php にリネームします。更にこのファイルをテキストエディタで開き、$cfg['Servers'][$i]['host'] 変数の値を先程環境変数で確認した hostname:port となるように書き換えて保存します。例えば hostname が 159.8.128.49、port が 3307 であった場合は以下のように指定して保存します:
  :
  :
$cfg['Servers'][$i]['host'] = '159.8.128.49:3307';
  :
  :

更に、phpMyAdmin を展開したフォルダ(この例であれば c:\tmp\phpmyadmin)に composer.json というファイルを以下の内容で作ります:
{}

また、同じフォルダ内に .bp-config という名前のフォルダを作り、更にその下に options.json というファイルを以下の内容で作ります:
{ "PHP_EXTENSIONS": [ "bz2", "zlib", "curl", "mcrypt", "mbstring", "mysql", "mysqli", "pdo", "pdo_mysql" ] }

この時点で phpMyAdmin を展開したフォルダ(c:\tmp\phpmyadmin\)はこのような感じになっています(.bp-config フォルダの下に options.json が保存されてます:
2016020801


これで phpMyAdmin を Bluemix で動かすための準備は整いました。cf ツールを使って、このフォルダ(c:\tmp\phpmyadmin\)以下をまとめて最初に作った PHP ランタイムにプッシュします:
2016020803


プッシュが成功したら、ウェブブラウザで PHP ランタイムの /phpMyAdmin/ フォルダにアクセスします。phpMyAdmin のログインページが表示され、ユーザー名とパスワードには環境変数から取得した username および password の値をそれぞれ入力して「実行」をクリックします:
2016020801


正しく入力されていれば、phpMyAdmin の初期画面になり、指定した MySQL サーバー内のデータベースが指定したユーザーの権限内で操作できるようになります。ここからテーブルを作成したり、クエリーを発行したりすることも可能です:
2016020802


Bluemix で phpMyAdmin を動かす場合の参考にしてください。

 

超っ速!と噂の PHP 7.0 がリリースされました。

というわけで、早速自分の CentOS 6 環境に導入してみました。手順はこんな感じで EPEL -> REMI とレポジトリを追加して yum で導入:
# cd /tmp
# yum -y install epel-release
# wget http://rpms.famillecollet.com/enterprise/remi-release-6.rpm
# rpm -Uvh remi-release-6.rpm
# yum -y install --enablerepo=remi --enablerepo=remi-php70 php

できたかな?
# php -v
PHP 7.0.2 (cli) (built: Jan  6 2016 15:33:31) ( NTS )
Copyright (c) 1997-2015 The PHP Group
Zend Engine v3.0.0, Copyright (c) 1998-2015 Zend Technologies

簡単でした。

MQTT をプログラミングで実装することを試みる場合、真っ先に思いつくのは Paho のライブラリを使うことです。Paho はオープンソースの MQTT ライブラリであり、多くの言語向けにクライアントライブラリが提供されています。この Paho を使うことができれば、比較的簡単に MQTT パブリッシャー/サブスクライバー機能を実装することが可能です:
http://www.eclipse.org/paho/
2016012501


ところが、Paho では PHP のライブラリは提供されていません。比較的利用者が多いと思われる PHP で MQTT を実装する場合、Paho 以外のライブラリを探す必要があるのですが、その候補の1つになりそうなのがオープンソースの phpMQTT です:
https://github.com/bluerhinos/phpMQTT


利用のための準備は非常に簡単で、上記サイトから phpMQTT.php ファイルをダウンロードするだけです。後はこのライブラリを読み込んで実装するだけ、です。

例えば MQTT パブリッシャーを実装する場合は、以下の様なコードを記述します(ファイル名は publish.php として、phpMQTT.php と同じディレクトリに作成します)。ダウンロードした phpMQTT.php を require で呼び出した上で、ホスト名、ポート番号、クライアント ID、トピック、そしてメッセージ本文といったパーツを単純に指定して、connect() して publish() メソッドを実行しているだけです:
<?php
require( "./phpMQTT.php" );

$mqtt_host = "quickstart.messaging.internetofthings.ibmcloud.com"; # MQTT ブローカー
$mqtt_port = 1883; # MQTT ポート番号
$mqtt_clientid = "d:quickstart:MyDevice:me.juge.mqtt.test"; # クライアントID
$mqtt_topic = "iot-2/evt/status/fmt/json"; # トピック文字列
$mqtt_message = '{"val1":123,"val2":"ABC"}'; # パブリッシュするメッセージ

$mqtt = new phpMQTT( $mqtt_host, $mqtt_port, $mqtt_clientid );
if( $mqtt->connect() ){
  $mqtt->publish( $mqtt_topic, $mqtt_message, 0 );
  $mqtt->close();
}
?>

↑上記のコードは IBM の IoT Foundation Quickstart 環境を想定してブローカーやクライアントID、トピックを指定しています。デバイス ID として "me.juge.mqtt.test" を指定してメッセージをパブリッシュしています。なので、IBM Bluemix の Node-RED 環境で IBM IoT インプットノードのデバイス ID に同じ文字列 "me.juge.mqtt.test" を設定すれば Node-RED にメッセージを送付することができます:
2016012501


(注 皆さんが試す場合は別のユニークな文字列を指定してください。要は PHP 内で指定するデバイス ID と、Node-RED で指定するデバイス ID が同じものを指定する必要がある、という意味です)


この状態で IBMIoT インプットノードに debug アウトプットノードを繋げて Node-RED アプリケーションをデプロイし、上記の PHP ファイルを実行します:
# php -f publish.php

するとコード内で記述された処理が実行され、IBM IoT Foundation Quickstart の MQTT ブローカー(quickstart.messaging.internetofthings.ibmcloud.com:1883)にメッセージが送信され、Node-RED 内の IBMIoT ノードが受け取り、このように画面内の debug タブに表示されれば成功です:
2016012502


PHP でも MQTT プログラミングができること、そして IBM の無料 MQTT ブローカーである QuickStart 環境にメッセージがパブリッシュできることが確認できました。



 

このページのトップヘ