加入收藏 | 设为首页 | 会员中心 | 我要投稿 焦作站长网 (https://www.0391zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > PHP教程 > 正文

PHP 5 数据对象 (PDO) 抽象层与 Oracle

发布时间:2020-03-22 04:38:00 所属栏目:PHP教程 来源:互联网
导读:PHP 5 数据对象 (PDO) 抽象层与 Oracle

// Open the .csv file for import
$fp = fopen('credits.csv', 'r');
while (!feof($fp)) {
 list($extension, $name) = fgetcsv($fp, 1024);
 $stmt->execute();
}
fclose($fp);

// Commit the changes
$dbh->commit();

?>


既然我们已经成功连接到了 Oracle,那么现在就可以创建一个表来保存一些数据了。对于此示例,我们使用一些 PHP 扩展及其作者,并将这些内容输入一个数据库中。数据库句柄对象的 exec() 方法可用来发出不会返回结果集的快速一次性查询,因此我们在这里使用该方法来发出 CREATE TABLE 查询。

为了使得示例更自然,我从 PHP 源代码中抽取了扩展及其作者的信息,并将其存储到了一个 CSV 文件中(请参见“相关附件:credits.csv”)。这就代表一个常见情形:从 CSV 文件批次导入数据。在我们的示例中,我们充分利用了 Oracle 的预处理语句和绑定参数,以获得一个高效的数据导入脚本。在讲述该示例之前,有必要了解一下 PDO 处理事务的方式。


PDO 中的事务处理


Oracle 具有一个敏感的默认操作模式:当您进行连接时,将会位于一个隐式事务处理中,在提交事务之前其中的更改不会完全生效。除了事务处理的标准优点(原子性、一致性、隔离性、可持久性 - ACID)之外,数据库服务器在执行每次更新之后还不需要重新构建索引和其他内部结构;它可以延迟到提交之后进行。这样会加速代码的执行。Oracle 这点确实很好。

但不幸的是,并非每个数据库供应商都支持事务处理,并且因为 PDO 旨在以一种相对可移植的方式支持这些事务处理,所以它默认情况下以自动提交模式运行。启用自动提交模式后,数据库驱动程序会隐式提交每个成功的更新。当您调用 $dbh->beginTransaction() 时,就会请求关闭自动提交,直到调用 $dbh->commit() 或者 $dbh->rollBack() 才会重新启用,具体取决于您的代码是怎样编写的。如果基础驱动程序不支持事务处理,则会抛出一个 PDOException。

如果发生了问题并且 PHP 出错,您的脚本将退出并且事务处于待批状态;或者您关闭数据库句柄时,PDO 会自动针对任何待批的事务调用 $dbh->rollBack()。此行为会减少向数据库中提交可能未定义或者已损坏数据的可能性,这是用于处理已放弃事务的标准语义。

预处理语句、存储过程


PDO 支持使用 Oracle 样式命名的占位符语法将变量帮定到 SQL 中的预处理语句(与 oci8 扩展中的 ocibindbyname() 类似)。PDO 还为其他数据库(如 ODBC)提供了命名占位符模拟,甚至可以为生来就不支持该概念的数据库(如 MySQL)模拟预处理语句和绑定参数。这是 PHP 向前迈进的积极一步,因为这样可以使开发人员能够用 PHP 编写“企业级”的数据库应用程序,而不必特别关注数据库平台的能力。

使用 PDO 预处理语句非常简单,调用数据库句柄的 prepare() 方法即可。它会返回一个语句句柄对象,然后您可以使用该对象来绑定参数和执行语句。在此示例中,我们将要定义两个命名占位符,“:extension”和“:name”,这两个占位符分别与 .CSV 文件中的 PHP 扩展名称和其中一个作者的姓名相对应。


$stmt = $dbh->prepare("INSERT INTO CREDITS (extension, name) VALUES (:extension, :name)");


预处理了语句之后,我们使用 bindParam() 方法来将这些命名参数分别与 PHP 变量名称“$extension”和“$name”相关联(这与 ocibindbyname() 类似)。我们还会通知 Oracle,这些数据将要格式化为字符串,最大长度为 64 个字符。


$stmt->bindParam(':extension', $extension, PDO_PARAM_STR, 64);
$stmt->bindParam(':name',      $name,      PDO_PARAM_STR, 64);


我们现在即准备好插入数据了 - 我们只需要打开该 CSV 文件,并从中获取数据即可。通过使用 fopen() 和 fgetcsv() 函数可以相当简单地完成此操作。然后,我们可以使用 PHP list() 构造函数直接将 CSV 的列指定给变量“$extension”和“$name”。因为这些变量已经绑定到了语句中,所以我们现在要做的只是调用该语句对象的 execute() 方法使其执行插入。这种方式既方便又快捷 - 在事务处理时每个迭代循环只有两行。到达文件尾时,我们就可以立即使用数据库句柄的 commit() 方法来提交这些更改了。

如果您只是要传递输入参数,并且有许多这样的参数要传递,那么您会觉得下面所示的快捷方式语法非常有帮助;此语法使您能够省去对 $stmt->bindParam() 的调用。


$stmt = $dbh->prepare("INSERT INTO CREDITS (extension, name) VALUES (:extension, :name)");
$stmt->execute(array(':extension' => $extension, ':name' => $name));


您还可以使用 bindParam 来为存储过程设置输入/输出参数;语法是完全相同的,只是查询有所不同。下面的代码演示如何调用一个名为“sp_add_item”的存储过程;其目的是要针对输入设置 $item_name,然后该存储过程将在返回时更新 $error_code。


$stmt = $dbh->prepare("begin sp_add_item(:item_name, :error_code); end");
$stmt->bindParam(':item_name', $item_name, PDO_PARAM_STR,  12);
$stmt->bindParam(':error_code', $error_code, PDO_PARAM_STR, 12);
$stmt->execute();


抓取数据


使用 PDO 抓取数据与进行插入或更新相似,只是您执行完查询之后,将要重复调用 fetch() 方法来获取结果集的下一行。进行获取的最简单情况如下所示,值得注意的一点是,您还可以将参数绑定到查询,以控制如 WHERE 子句这样的内容;执行此操作的语法与我们已经看到的 bindParam() 代码完全相同。

$stmt = $dbh->prepare("SELECT extension, name from CREDITS");
if ($stmt->execute()) {
while ($row = stmt->fetch()) {
print_r($row);
    }
}


PDO 支持一些不同的抓取策略,这些策略在方便性和性能方面有所差别;通过将下列选项之一指定为 fetch() 方法的参数,您可以更改其返回值以适应您的语法:


·PDO_FETCH_NUM - 每个行抓取返回一个按照列位置索引的数组,并且以 0 为基数(第一列是第 0 个元素)。

while ($row = $stmt->fetch(PDO_FETCH_NUM)) {
 printf("Extension %s, by %s<br>", $row[0], $row[1]);
}


·PDO_FETCH_ASSOC - 每个行抓取根据行集中的列名,返回一个按列名索引的数组。

while ($row = $stmt->fetch(PDO_FETCH_ASSOC)) {
 echo "Extension $row[EXTENSION] by $row[NAME]<br>";
}

(编辑:焦作站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读