如何:將資料當做物件擷取
SQL Server Driver for PHP 會提供 sqlsrv_fetch_object 函數,將資料列當做 PHP 物件擷取。本主題描述在 sqlsrv_fetch_object 的呼叫中使用選擇性 $className 參數時,要如何擷取資料。如需示範如何將資料當做物件擷取而不使用選擇性 $className 參數的範例,請參閱<sqlsrv_fetch_object>。
如果使用選擇性 $className 參數來指定類別名稱,便會具現化此類別類型的物件。如果此類別的屬性名稱符合結果集欄位名稱,對應的結果集值便會套用到屬性。如果結果集欄位名稱不符合類別屬性,具有結果集欄位名稱的屬性便會加入到物件中,而且結果集值會套用到此屬性。
以下規則適用於使用 $className 參數指定類別時:
- 比對會區分大小寫。例如,屬性名稱 CustomerId 不符合欄位名稱 CustomerID。在此情況下,CustomerID 屬性將會加入到物件中,而且 CustomerID 欄位的值會提供給 CustomerID 屬性。
- 不論存取修飾詞為何都會發生比對。例如,如果指定的類別具有的私用屬性名稱符合結果集欄位名稱,結果集欄位中的值會套用到此屬性。
- 類別屬性資料類型會被忽略。如果結果集中的 "CustomerID" 欄位是字串,但是此類別的 "CustomerID" 屬性是整數,則結果集中的字串值會寫入 "CustomerID" 屬性。
- 如果指定的類別不存在,此函數會傳回 false,並將錯誤加入到錯誤集合。如需有關擷取錯誤資訊的詳細資訊,請參閱<sqlsrv_errors>。
範例
下列範例會將結果集的每一個資料列當做指令碼內定義的 Product 類別執行個體來擷取。此範例會從 AdventureWorks 資料庫中,針對指定到期日 (DueDate) 和庫存數量 (StockQty) 少於指定值的產品來擷取 Purchasing.PurchaseOrderDetail 和 Production.Product 資料表中的產品資訊。此範例強調在 sqlsrv_fetch_object 的呼叫中指定類別時所適用的某些規則:
- $product 變數是 Product 類別的執行個體,因為指定 "Product" 時使用了 $className 參數,而且有 Product 類別存在。
- Name 屬性會加入到 $product 執行個體,因為現有的 name 屬性並不相符。
- 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 內指定資料行名稱的一個方法:
SELECT SCOPE_IDENTITY() AS PictureID