データをオブジェクトとして取得する方法
SQL Server Driver for PHP には、データの行を PHP オブジェクトとして取得するための sqlsrv_fetch_object 関数が用意されています。このトピックでは、sqlsrv_fetch_object の呼び出しで省略可能な $className パラメータを使用してデータを取得する方法について説明します。省略可能な $className パラメータを使用せずにデータをオブジェクトとして取得する方法を示す例については、「sqlsrv_fetch_object」を参照してください。
省略可能な $className パラメータでクラス名が指定された場合、このクラスの型のオブジェクトがインスタンス化されます。クラスのプロパティの名前が結果セットのフィールド名と同じ場合、対応する結果セットの値がプロパティに適用されます。結果セットのフィールド名がクラスのプロパティと異なる場合、結果セットのフィールド名を持つプロパティがオブジェクトに追加され、結果セットの値がプロパティに適用されます。
$className パラメータでクラスを指定するときには次の規則が適用されます。
- 照合で大文字と小文字が区別されます。たとえば、プロパティ名 CustomerId はフィールド名 CustomerID と一致しません。この場合は、オブジェクトに CustomerID プロパティが追加され、そのプロパティに CustomerID フィールドの値が適用されます。
- 照合はアクセス修飾子に関係なく行われます。たとえば、指定したクラスに、結果セットのフィールド名と名前が一致するプライベート プロパティがあった場合、そのプロパティにその結果セット フィールドの値が適用されます。
- クラスのプロパティのデータ型は無視されます。結果セットの "CustomerID" フィールドが文字列の場合、クラスの "CustomerID" プロパティが整数でも、結果セットの文字列値が "CustomerID" プロパティに書き込まれます。
- 指定したクラスが存在しない場合は false が返され、エラー コレクションにエラーが追加されます。エラー情報の取得については、「sqlsrv_errors」を参照してください。
例
次の例では、結果セットの各行を、スクリプトで定義されている Product クラスのインスタンスとして取得します。この例では、AdventureWorks データベースの Purchasing.PurchaseOrderDetail テーブルと Production.Product テーブルから、指定した期限 (DueDate) を持ち、在庫数量 (StockQty) が指定した値より少ない製品に関する製品情報を取得します。この例は、sqlsrv_fetch_object の呼び出しでクラスを指定するときに適用されるルールのいくつかを強調しています。
- $className パラメータで "Product" が指定されていて、Product クラスが存在するため、$product 変数は Product クラスのインスタンスです。
- 既存の name プロパティとは一致しないため、Name プロパティが $product インスタンスに追加されます。
- 一致するプロパティがないため、Color プロパティが $product インスタンスに追加されます。
- プライベート プロパティ UnitPrice に UnitPrice フィールドの値が設定されます。
この例では、SQL Server と AdventureWorks データベースがローカル コンピュータにインストールされていることを前提としています。この例をコマンド ラインから実行した場合、すべての出力はコンソールに書き込まれます。
<?php
/* Define the Product class. */
class Product
{
/* Constructor */
public function Product($ID)
{
$this->objID = $ID;
}
public $objID;
public $name;
public $StockedQty;
public $SafetyStockLevel;
private $UnitPrice;
function getPrice()
{
return $this->UnitPrice;
}
}
/* Connect to the local server using Windows Authentication, and
specify the AdventureWorks database as the database in use. */
$serverName = "(local)";
$connectionInfo = array( "Database"=>"AdventureWorks");
$conn = sqlsrv_connect( $serverName, $connectionInfo);
if( $conn === false )
{
echo "Could not connect.\n";
die( print_r( sqlsrv_errors(), true));
}
/* Define the query. */
$tsql = "SELECT Name,
SafetyStockLevel,
StockedQty,
UnitPrice,
Color
FROM Purchasing.PurchaseOrderDetail AS pdo
JOIN Production.Product AS p
ON pdo.ProductID = p.ProductID
WHERE pdo.StockedQty < ?
AND pdo.DueDate= ?";
/* Set the parameter values. */
$params = array(3, '2002-01-29');
/* Execute the query. */
$stmt = sqlsrv_query( $conn, $tsql, $params);
if ( $stmt )
{
echo "Statement executed.\n";
}
else
{
echo "Error in statement execution.\n";
die( print_r( sqlsrv_errors(), true));
}
/* Iterate through the result set, printing a row of data upon each
iteration. Note the following:
1) $product is an instance of the Product class.
2) The $ctorParams parameter is required in the call to
sqlsrv_fetch_object, because the Product class constructor is
explicity defined and requires parameter values.
3) The "Name" property is added to the $product instance because
the existing "name" property does not match.
4) The "Color" property is added to the $product instance
because there is no matching property.
5) The private property "UnitPrice" is populated with the value
of the "UnitPrice" field.*/
$i=0; //Used as the $objID in the Product class constructor.
while( $product = sqlsrv_fetch_object( $stmt, "Product", array($i)))
{
echo "Object ID: ".$product->objID."\n";
echo "Product Name: ".$product->Name."\n";
echo "Stocked Qty: ".$product->StockedQty."\n";
echo "Safety Stock Level: ".$product->SafetyStockLevel."\n";
echo "Product Color: ".$product->Color."\n";
echo "Unit Price: ".$product->getPrice()."\n";
echo "-----------------\n";
$i++;
}
/* Free statement and connection resources. */
sqlsrv_free_stmt( $stmt);
sqlsrv_close( $conn);
?>
sqlsrv_fetch_object 関数は、常に既定の PHP データ型に従ってデータを返します。PHP データ型を指定する方法の詳細については、「PHP データ型を指定する方法」または「単一のフィールドを取得する方法」を参照してください。
名前のないフィールドが返された場合、sqlsrv_fetch_object によってフィールド値が破棄され、警告が発行されます。例として、データベース テーブルに値を挿入し、サーバーで生成される主キーを取得する、次の Transact-SQL ステートメントについて考えてみます。
INSERT INTO Production.ProductPhoto (LargePhoto) VALUES (?);
SELECT SCOPE_IDENTITY()
このクエリから返される結果を sqlsrv_fetch_object で取得すると、SELECT SCOPE_IDENTITY()
から返される値が破棄され、警告が発行されます。これを回避するため、Transact-SQL ステートメントで、返されるフィールドの名前を指定できます。以下は、Transact-SQL で列名を指定する 1 つの方法です。
SELECT SCOPE_IDENTITY() AS PictureID