通过缓存数据库结果提高PHP性能

来源:Oracle中国 作者: 2007-12-14 出处:pcdog.com

oracle  qos  sql 存储过程  stp  解决方案  
上一页 1 2 3 4 下一页 
  构建客户端

  现在,您已经针对 ORDERS 和 ORDER_ITEMS 表创建了注册,下面我们将了解一下访问这些表中存储的订单及其订单项的客户端应用程序如何使用更改通知。为此,您可以构建一个 PHP 应用程序,它将缓存针对以上表的查询结果,并采取相应的操作来响应有关对这些表所做更改的通知(从数据库服务器中收到这些通知)。一个简单的方法是使用 PEAR::Cache_Lite 程序包,它为您提供了一个可靠的机制来使缓存数据保持最新状态。尤其是,您可以使用 Cache_Lite_Function 类(PEAR::Cache_Lite 程序包的一部分),通过该类您可以缓存函数调用。

  例如,您可以创建一个函数来执行下列任务:建立数据库连接、针对该数据库执行 select 语句、获取检索结果并最终以数组形式返回结果。然后,您可以通过 Cache_Lite_Function 实例的 call 方法缓存由该函数返回的结果数组,以便可以从本地缓存而不是从后端数据库读取这些数组,这样可以显著提高应用程序的性能。然后,在收到缓存数据更改的通知时,您将使用 Cache_Lite_Function 实例的 drop 方法删除缓存中的过期数据。

  回过头来看看本文的示例,您可能要创建两个函数,用于应用程序与数据库交互:第一个函数将查询 ORDERS 表并返回具有指定 ID 的订单,而另一个函数将查询 ORDER_ITEMS 表并返回该订单的订单项。“清单 4”显示了包含 getOrderFields 函数(该函数接受订单 ID 并返回一个包含所检索到订单的某些字段的关联数组)的 getOrderFields.php 脚本。

  清单 4. 获取指定订单的字段
<?php 
//File:getOrderFields.php 
require_once 'connect.php'; 
function getOrderFields($order_no) { 
if (!$rsConnection = GetConnection()){ 
return false; 
   } 
$strSQL = "SELECT TO_CHAR(ORDER_DATE) ORDER_DATE, CUSTOMER_ID,  
ORDER_TOTAL FROM ORDERS WHERE order_id =:order_no"; 
$rsStatement = oci_parse($rsConnection,$strSQL); 
oci_bind_by_name($rsStatement, ":order_no", $order_no, 12); 
if (!oci_execute($rsStatement)) { 
$err = oci_error(); 
print $err['message']; 
trigger_error('Query failed:' . $err['message']); 
return false; 
   } 
$results = oci_fetch_assoc($rsStatement); 
return $results; 
 } 
?> 

  “清单 5”是 getOrderItems.php 脚本。该脚本包含 getOrderItems 函数,该函数接受订单 ID 并返回一个二维数组,该数组包含表示订单的订单项的行。

  清单 5. 获取指定订单的订单项
<?php 
//File:getOrderItems.php 
require_once 'connect.php'; 
function getOrderItems($order_no) { 
if (!$rsConnection = GetConnection()){ 
return false; 
   } 
$strSQL = "SELECT * FROM ORDER_ITEMS WHERE  
order_id =:order_no ORDER BY line_item_id"; 
$rsStatement = oci_parse($rsConnection,$strSQL); 
oci_bind_by_name($rsStatement, ":order_no", $order_no, 12); 
if (!oci_execute($rsStatement)) { 
$err = oci_error(); 
trigger_error('Query failed:' . $err['message']); 
return false; 
   } 
$nrows = oci_fetch_all($rsStatement, $results); 
return array ($nrows, $results); 
 } 
?> 

  注意,以上两个函数都需要 connect.php 脚本,该脚本应包含返回数据库连接的 GetConnection 函数。清单 6 就是 connect.php 脚本:

  清单 6. 获取数据库连接
<?php 
//File:connect.php 
function GetConnection() { 
$dbHost = "dbserverhost"; 
$dbHostPort="1521"; 
$dbServiceName = "orclR2"; 
$usr = "oe"; 
$pswd = "oe"; 
$dbConnStr = "(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=".$dbHost.") 
(PORT=".$dbHostPort."))(CONNECT_DATA=(SERVICE_NAME=".$dbServiceName.")))"; 
if(!$dbConn = oci_connect($usr,$pswd,$dbConnStr)) { 
$err = oci_error(); 
trigger_error('Failed to connect ' .$err['message']); 
return false; 
      } 
return $dbConn; 
  } 
?> 

  现在,您已经创建了与数据库通信所需的所有函数,下面我们将了解一下 Cache_Lite_Function 类的工作方式。清单 7 是 testCache.php 脚本,该脚本使用 Cache_Lite_Function 类缓存以上函数的结果。

  清单 7. 使用 PEAR::Cache_Lite 缓存
<?php 
//File:testCache.php 
require_once 'getOrderItems.php'; 
require_once 'getOrderFields.php'; 
require_once 'Cache/Lite/Function.php'; 

$options = array(  
'cacheDir' => '/tmp/',  
'lifeTime' => 86400  
 );  

if (!isset($_GET['order_no'])) { 
die('The order_no parameter is required'); 
  }  

$order_no=$_GET['order_no']; 
$cache = new Cache_Lite_Function($options); 
if ($orderfields = $cache->call('getOrderFields', $order_no)){ 
print "<h3>ORDER #$order_no</h3>\n"; 
print "<table>"; 
print "<tr><td>DATE:</td><td>".$orderfields['ORDER_DATE']."</td></tr>"; 
print "<tr><td>CUST_ID:</td><td>".$orderfields['CUSTOMER_ID']."</td></tr>"; 
print "<tr><td>TOTAL:</td><td>".$orderfields['ORDER_TOTAL']."</td></tr>"; 
print "</table>"; 
} else { 
print "Some problem occurred while getting order fields!\n"; 
$cache->drop('getOrderFields', $order_no); 
 } 

if (list($nrows, $orderitems) = $cache->call('getOrderItems', $order_no)){ 
//print "<h3>LINE ITEMS IN ORDER #$order_no</h3>"; 
print "<table border=1>"; 
print "<tr>\n"; 
while (list($key, $value) = each($orderitems)) { 
print "<th>$key</th>\n"; 
  } 
print "</tr>\n"; 
for ($i = 0; $i < $nrows; $i++) { 
print "<tr>"; 
print "<td>".$orderitems['ORDER_ID'][$i]."</td>"; 
print "<td>".$orderitems['LINE_ITEM_ID'][$i]."</td>"; 
print "<td>".$orderitems['PRODUCT_ID'][$i]."</td>"; 
print "<td>".$orderitems['UNIT_PRICE'][$i]."</td>"; 
print "<td>".$orderitems['QUANTITY'][$i]."</td>"; 
print "</tr>"; 
  } 
print "</table>"; 
} else { 
print "Some problem occurred while getting order line items"; 
$cache->drop('getOrderItems', $order_no); 
 } 
?> 

  “清单 7”中的 testCache.php 脚本应与 order_no URL 参数(代表 OE.ORDER 表中存储的订单 ID)一起被调用。例如,要检索与 ID 为 2408 的订单相关的信息,需要在浏览器中输入如下所示的 URL:
http://webserverhost/phpcache/testCache.php?order_no=2408
  结果,浏览器将生成以下输出:

  ORDER #2408

DATE: 29-JUN-99 06.59.31.333617 AM
CUST_ID: 166
TOTAL: 309

ORDER_ID LINE_ITEM_ID PRODUCT_ID UNIT_PRICE QUANTITY
2408 1 2751 61 3
2408 2 2761 26 1
2408 3 2783 10 10

更多内容请看PCdog.com--PHP与数据库  数据库相关文章专题
上一页 1 2 3 4 下一页 
上一篇:为什么说用PHP开发大型系统令人不爽
下一篇:PHP5 OOP编程中的代理与异常定制