書籍転載
Windows Azure 実践クラウド・プログラミング
for C#/Visual Basic/PHP

PHPでWindows Azureテーブル・ストレージを活用しよう
―Chapter 7 PHPによるWindows Azureアプリケーション開発(後編) ―

山田 祥寛
2010/09/15
Page1 Page2

7-4 SQL Azure利用の基本

 なお、本節の内容を実行するには、「PHP+EclipseでWindows Azureアプリケーションを開発しよう」の「PHP+Azureアプリケーションの基本」の手順でも見たように、あらかじめプロジェクトでSQL Azureへのアクセスを有効にしておく必要があります。さもないと、必要な拡張モジュールが有効化されないためです。

SQL Azure利用の準備

 SQL Azureを利用するには、まず5-2節(本転載では割愛)の手順に従って、SQL Azureのアカウントを作成すると共に、必要なデータベース/テーブルを作成しておく必要があります。

 その上で、プロジェクトに対して、SQL Azureへの接続情報を登録しておきましょう。接続情報を登録するには、ロールプロジェクト(ここではAzurePhp_WebRole)のプロパティシートを表示します。プロパティシートの左ツリーでは、[Windows Azure]−[SQL Azure]を選択してください。

図7-25:ロールプロジェクトのプロパティシート

 Azureポータルサイトから入手したホスト名、データベース、ユーザ名、パスワードを入力し、[接続のテスト]ボタンをクリックしてください。[成功]ダイアログが表示されれば、設定は正しく入力できています。

 プロパティシートを閉じて、connect.phpが自動生成されていることも確認しておきましょう。

<?php
// ===Created by Azure PDT===
$host = "j9hn0cln8f.database.windows.net";
$dbname = "AzureSql";
$dbuser = "yyamada@j9hn0cln8f";
$dbpwd = "**********";
$driver = "{SQL Server Native Client 10.0}";
  ...後略...
リスト7-8 connect.php

 connect.phpは、SQL Azureへの接続情報を変数として定義しただけのファイルです。環境依存の情報を個別のスクリプトに分散するのは好ましくありませんので、このようにひとつのファイルで定義したものを、個別のスクリプトからはインポートして利用するようにすると良いでしょう。

 connect.phpの末尾には、SQL Azureに接続するためのサンプルコードがコメントで示されていますが、動作には不要なものですので、削除してしまって構いません。

一言掲示板の実装

 環境の準備ができたところで、SQL Azureを利用したアプリケーションを作成していきます。本項で作成するのは、前節でも作成した一言掲示板のSQL Azure版です。

図7-26:投稿内容を一覧表示

 新規のSqlBbs.phpを作成し、リスト7-9のようなコードを記述します。

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN">
<html>
<head>
<meta http-equiv="Content-Type"
  content="text/html; charset=utf-8">
<title>一言掲示板</title>
</head>
<body>
<form method="POST" action="">
  名前:
  <input type="text" name="txtName" /><br />
  URL:
  <input type="text" name="txtUrl" size="50" /><br />
  本文:
  <input type="text" name="txtBody" size="75" /><br />
  <input type="submit" value="投稿" />
</form>

<?php
require_once 'MyLib.php'; // 自作の関数ライブラリ
require_once 'connect.php'; // 接続情報


// SQL Azureへの接続
$db = sqlsrv_connect($host,
  array(
    'Database' => $dbname,
    'UID' => $dbuser,
    'PWD' => $dbpwd,
    'CharacterSet' => 'UTF-8',
    'MultipleActiveResultSets' => '0'))
  or die('接続に失敗しました。');

// 名前/本文が入力された場合、レコードの追加処理
if (isset($_POST['txtName']) && isset($_POST['txtBody'])) {
 
  // 挿入処理を実行
  sqlsrv_query($db,
    'INSERT INTO Message (bbs, name, url, body, updated)
      VALUES(?, ?, ?, ?, DATEADD(hour, 9, SYSDATETIME()))',
    array(
      'php',
      $_POST['txtName'],
      $_POST['txtUrl'],
      $_POST['txtBody']
  ));
}


// Messageテーブルの内容をupdatedフィールド降順で取得&順に表示
$stmt = sqlsrv_query(
  $db, 'SELECT * FROM Message ORDER BY updated DESC');
?>
<table border="1">
<tr>
  <th>名前</th><th>本文</th><th>投稿日時</th>
</tr>

<?php while($row =
    sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) { ?>
  <tr>
  <td><a href="<?php e($row['url']); ?>">
   <?php e($row['name']); ?></a></td>
  <td><?php e($row['body']); ?></td>
  <td><?php print($row['updated']->format('Y/m/d H:i:s')); ?></td>
  </tr>
<?php } ?>
</table>
</body>
</html>
リスト7-9 SqlBbs.php

 SQL Azureを操作するには、SQL Server Driver for PHP(以降、SQL Server関数)を利用します。SQL Server関数は、PHPアプリケーションからSQL Server 2005/2008にアクセスするための拡張モジュールです。MySQL、PostgreSQL関数などともよく似たつくりとなっていますので、これらの専用データベース関数を利用したことがある方ならば、ほとんど同じ感覚で利用できるでしょう。

 SQL Server関数はすべて「sqlsrv_.」というプレフィックスで始まります。

データベースに接続する

 まずは、SQL Azureデータベースへの接続からです。データベースへの接続には、sqlsrv_connect関数を利用します。

resource sqlsrv_connect(string $host [,array $info])
構文 sqlsrv_connect関数
$host:ホスト名 $info:接続情報(「キー=>値」の連想配列)

 引数$infoに指定できる接続情報には、表7-4のようなものがあります。

キー 概要 デフォルト値
UID SQL Azureに接続する際の認証ユーザ
PWD SQL Azureに接続する際の認証パスワード
Database 接続するデータベース (ログインの既定)
CharacterSet 文字エンコーディング SQLSRV_ENC_CHAR
ConnectionPooling 接続プールを利用するか TRUE
Encrypt 暗号化を有効にするか FALSE
LoginTimeout 接続タイムアウト時間(秒) 無期限
TransactionIsolation トランザクション分離レベル(SQLSRV_TXN_READ_UNCOMMITTED|SQLSRV_TXN_READ_COMMITTED|SQLSRV_TXN_REPEATABLE_READ|SQLSRV_TXN_SNAPSHOT|SQLSRV_TXN_SERIALIZABLE) SQLSRV_TXN_READ_
COMMITTED MultipleActiveResultSets MARS(Multiple Active ResultSet)を有効にするか FALSE
ReturnDatesAsStrings 日付/時刻を文字列として返すか FALSE
表7-4 SQL Azureへの接続情報(引数$infoのキー情報)

 これら接続情報のうち、UID、PWD、Database、CharacterSetは必須です。正確にはCharcterSetは指定してなくてもエラーにはなりませんが、明確に文字エンコーディングを指定していない場合、マルチバイト文字列が文字化けする原因になりますので、要注意です。

 接続に成功した場合、sqlsrv_connect関数は接続リソース(resource型)を返します。以降の操作は、この接続リソースをキーにして行います。

SQL Azureに問い合わせ(クエリ)を発行する

 接続が確立できたら、sqlsrv_query関数で問い合わせを発行します。

resource sqlsrv_query(resource $con, string $tsql [,array $params])
構文 sqlsrv_query関数
$con:接続リソース
$tsql:クエリ
$params:バインドするパラメータ

 クエリ(引数$tsql)に含まれる「?」はプレイスホルダです。引数$paramsで、配列形式で具体的な値(リテラル/変数)を割り当てることができます。

図7-27:プレイスホルダとsqlsrv_query関数

 ユーザからの入力値などに基づいてクエリを組み立てる場合には、原則として、このプレイスホルダのしくみを利用するようにしてください*30

*30 文字列連結で動的にSQLを組み立てるのは、極力避けるべきです。適切なエスケープ処理を行っていない場合、SQLインジェクション脆弱性の原因となるためです。

 なお、他の箇所でも説明していますが、現在時刻を求めるSYSDATETIME関数は、世界標準時刻として返されます。日本標準時に変更するには、DATEADD関数を利用して、時差(9時間)を加算するようにしてください。

【Note】sqlsrv_prepare/sqlsrv_execute関数

 その場でクエリを発行するsqlsrv_query関数が1回限りのクエリ実行に適しているのに対して、複数回にわたって同一の(パラメータ値のみ異なる)クエリを実行したい場合には、sqlsrv_prepare/sqlsrv_execute関数が適しています。

 以下は、リスト7-9をsqlsrv_prepare/sqlsrv_execute関数で書き換えた例です。

$stmt = sqlsrv_prepare($db,
    'INSERT INTO Message (bbs, name, url, body, updated)
    VALUES(?, ?, ?, ?, DATEADD(hour, 9, SYSDATETIME()))',
  array(&$bbs, &$name, &$url, &$body));
$bbs = 'php';
$name = $_POST['txtName'];
$url = $_POST['txtUrl'];
$body = $_POST['txtBody'];
sqlsrv_execute($stmt);

 sqlsrv_prepare関数を実行した時点では、まだクエリと、プレイスホルダに割り当てるべき変数(参照)を設定/準備しているだけで、クエリそのものが発行されているわけではない点に注意してください。sqlsrv_prepare関数は、戻り値としてクエリを実行するためのステートメントリソースを返します。

 クエリが準備できたら、それぞれの変数に対して、具体的な値を割り当てたうえで、sqlsrv_execute関数でクエリを発行します。

 変数の割り当て→クエリの実行を繰り返すことで、同じクエリを何度も再利用できるのが特徴です。

SELECT命令を発行する

 SELECT命令の発行にも、sqlsrv_query関数は利用できます*31 では触れませんでしたが、sqlsrv_query関数の戻り値はステートメントリソースです。ステートメントリソースとは、発行すべきクエリそのものを表すと共に、クエリによる実行結果を管理するためのリソースと考えれば良いでしょう。

*31 もちろん、sqlsrv_prepare/sqlsrv_execute関数も同様です。

 INSERT/UPDATE/DELETE命令などによって影響を受けた行数や、SELECT命令によって取得した結果セットにアクセスするには、このステートメントリソースを利用します。

結果セットを取得する

 結果セットを読み込む場合には、先頭からレコード(行)単位に読み込んでいくのが基本です。この時、「現在読み込み可能な行」を表す内部的な目印のことをレコードポインタ、また、レコードポインタが表す現在行のことをカレントレコードと言います。

 sqlsrv_query関数で結果セットを生成した直後の段階では、レコードポインタは「先頭行の直前」を示しています。このレコードポインタを次のレコードに移動しながら、その行の内容を読み込んでいく*32には、sqlsrv_fetch_array関数を利用します。

*32 フェッチする、と言います。

array sqlsrv_fetch_array(resource $stmt [,int $type]))
構文 sqlsrv_fetch_array関数
$stmt:ステートメントリソース
$type:フェッチモード(SQLSRV_FETCH_NUMERIC|SQLSRV_FETCH_ASSOC)

 行をどのように取得するかは、引数$typeで指定します。SQLSRV_FETCH_NUMERICでは列番号と値からなる通常配列を、SQLSRV_FETCH_ASSOCは列名と値からなる連想配列を返します。また、次の行が存在しない場合(結果セットの終端に到達した場合)、sqlsrv_fetch_array関数はFALSEを返します。

  では、sqlsrv_fetch_array関数のこの性質を利用して、関数がFALSEを返すまでwhileループを繰り返すことで、結果セット内のすべてのレコードを取得してるわけです。

図7-28:結果セットとレコードポインタ

 サンプルでは、連想配列としてレコードをフェッチしていますので、それぞれのフィールドには$row['name']のようにアクセスできます。なお、日付/時刻型のupdatedフィールドはDateTimeオブジェクトとして返されますので、これをformatメソッドで整形した上で出力しています。

【Column】Windows Azureをより学ぶために

 Windows Azureは、それ自体がとても広範なテーマです。本書でもできるだけ包括的な解説を心がけていますが、本格的にWindows Azureの習得を目指すならば、関連書籍/資料による学習は欠かすことができません。以下に、Windows Azure学習に役立つ書籍/資料をまとめておきます。本書の学習と並行して、活用することをお勧めします。

(1)基本技術を理解する

 本書「はじめに」でも紹介したように、本書は読者の方が.NET Frameworkの基礎を理解していることを前提にした解説書です。もしも本書を読み進めるうえで、周辺知識の理解が足りていないな、もっと知りたいな、と思ったら、以下のような書籍も合わせて参照することをお勧めします。

(2)Windows Azureの理解をより深める

 Windows Azureを学ぶ上で、Windows Azure Platformデベロッパーセンターはまず最初に見ておくべき資料です。概要資料やトレーニングキット、ラーニングは、きっと本書での学習内容を補完するのに役立つでしょう。

 [ライブラリ]メニューから辿れるドキュメントは執筆時点でまだ英語ですが、Windows Azure Platformに関する情報が体系的にまとまっていますので、自分の興味のあるところから徐々に読み進めていくと良いでしょう。

 [コミュニティ]メニューから辿れるCode Garelly/CodePlexではマイクロソフトやコミュニティから提供されるツールやサンプルを入手できます。本書でも紹介しているWindows Azure Management ToolやManagement CmdLetsも、ここで公開されています。

(3)最新情報を収集する

 Windows Azureは日々進化しています。そのダイナミックな変化をリアルタイムに追跡したいならば、マイクロソフトのエバンジェリスト諸氏や開発チームが執筆しているブログを購読するのが良いでしょう。

 また、Twitterを流れる情報にも注目です。@shin135@WindowsAzure@SQLAzure@Azure_AppFabricなどのアカウント、ハッシュタグとして#Azureはフォローしておくと、なにかと最新情報を捉えやすいと思います。

 その他、上で紹介したものと重複するものもありますが、Windows Azure Communityのリンク集がよくまとまっています。Azure自体の進化と共に、Azureに関する情報も日々充実しつづけている状況ですので、実際にAzureを導入しようと考えている方は、ぜひ、インターネット上の情報にも広く目を向けるようにしてください。

 「Chapter 7 PHPによるWindows Azureアプリケーション開発」は今回で終了です。次回は「Chapter 4  Windows Azureストレージ - テーブル/キュー/ドライブ編 -」の中から、「クラウド環境の仮想的なNTFSファイルシステム - ドライブ -」の部分を転載します。End of Article

 

 INDEX
  [書籍転載]Windows Azure 実践クラウド・プログラミング for C#/Visual Basic/PHP
  PHPでWindows Azureテーブル・ストレージを活用しよう
    1.テーブルストレージ利用の基本
  2.SQL Azure利用の基本

インデックス・ページヘ 「Windows Azure 実践クラウド・プログラミング for C#/Visual Basic/PHP」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間