开放数据库互连(Open Database Connectivity,ODBC) 与PDO 事务的四个特征 XSS

什么是DBMS ——database manage system 

ODBC 的出现是为了方便DBMS 之间实现数据库的沟通,是一个定义好的驱动

事务的 4 个特征:原子性(Atomicity)、一致性(Consistency)、独立性(Isolation)和持久性(Durability),即 ACID

如何使用 PDO 连接到 DB2
try { $dbh = new PDO('odbc:SAMPLE', 'db2inst1', 'ibmdb2'); echo "Connected\n";} catch (Exception $e) { echo "Failed: " . $e->getMessage();}
odbc:SAMPLE 告诉 PDO 它应该使用 ODBC 驱动程序,并且应该使用 "SAMPLE" 数据库。如果使用一个驱动程序管理器,那么可以用一个 ODBC 级 数据源名称替代 SAMPLE。实际上,在冒号 字符之后可以指定任何有效的 ODBC 数据源连接字符串。
如果连接成功,您将看到消息 "Connected",否则,PDO 将抛出一个 PDOException,解释为什么连接失败。可能的原因包括无效的参数,不正确的用户/密码,甚至是您忘了装载驱动程序。

在事务中执行批处理
try { $dbh = new PDO('odbc:SAMPLE', 'db2inst1', 'ibmdb2', array(PDO_ATTR_PERSISTENT => true)); echo "Connected\n"; $dbh->setAttribute(PDO_ATTR_ERRMODE, PDO_ERRMODE_EXCEPTION); $dbh->beginTransaction(); $dbh->exec("insert into staff (id, first, last) values (23, 'Joe', 'Bloggs')"); $dbh->exec("insert into salarychange (id, amount, changedate) values (23, 50000, NOW())"); $dbh->commit(); } catch (Exception $e) { $dbh->rollBack(); echo "Failed: " . $e->getMessage(); }
在上面的示例中,假设我们为一个新雇员创建一组条目,这个雇员有一个 ID 号,即 23。除了输入这个人的基本数据外,我们还需要记录雇员的薪水。两个更新分别完成起来很简单,但通过将这两个更新包括在 beginTransaction() 和 commit() 调用中,就可以保证在更改完成之前,其他人无法看到更改。如果发生了错误,catch 块可以 回滚 事务开始以来发生的所有更改,并打印出一条错误消息。
并不是一定要在事务中作出更新。您也可以发出复杂的查询来提取数据,还可以使用那种信息构建更多的更新和查询。当事务在活动时,可以保证其他人在工作进行当中无法作出更改。事实上,这不是 100% 的正确,但如果您之前没有听说过事务的话,这样介绍也未尝不可。

XSS 也是一个类似的问题。不过这一次不受信任的数据瞄准的是浏览站点的人们,而不是应用程序本身。通过提交包含 HTML 或 javascript 组合的文本,攻击者期望您之后会将那种数据直接输出到其他访问站点的人那里,从而使恶意代码可以在站点访问者的浏览器上运行。

预处过程

很多更成熟的数据库都支持预处理语句的概念。什么是预处理语句?您可以把预处理语句看作您想要运行的 SQL 的一种编译过的模板,它可以使用变量参数进行定制。预处理语句可以带来两大好处:
查询只需解析(或准备)一次,但是可以用相同或不同的参数执行多次。当查询准备好后,数据库将分析、编译和优化执行该查询的计划。对于复杂的查询,这个过程要花比较长的时间,如果您需要以不同参数多次重复相同的查询,那么该过程将大大降低应用程序的速度。通过使用预处理语句,可以避免重复分析/编译/优化周期。简言之,预处理语句使用更少的资源,因而运行得更快。 提供给预处理语句的参数不需要用引号括起来,驱动程序会处理这些。如果应用程序独占地使用预处理语句,那么可以确保没有 SQL 入侵发生。(然而,如果您仍然将查询的其他部分建立在不受信任的输入之上,那么就仍然存在风险)。 预处理语句是如此有用,以致 PDO 实际上打破了在目标 4 中设下的规则:如果驱动程序不支持预处理语句,那么 PDO 将仿真预处理语句。
下面是使用预处理语句的两个例子。第一个例子 通过替换指定 占位符的 name 和 value,执行一次插入。而 第二个例子 使用问号占位符执行一条 select 语句。
清单 4. 使用预处理语句的重复插入
$stmt = $dbh->prepare("INSERT INTO REGISTRY (name, value) VALUES (:name, :value)"); $stmt->bindParam(':name', $name);$stmt->bindParam(':value', $value); // insert one row$name = 'one';$value = 1;$stmt->execute(); // insert another row with different values$name = 'two';$value = 2; $stmt->execute();
清单 5. 使用预处理语句取数据
$stmt = $dbh->prepare("SELECT * FROM REGISTRY where name = ?"); if ($stmt->execute(array('one'))) { while ($row = $stmt->fetch()) { print_r($row); }}
如果数据库驱动程序支持,您还可以绑定输出和输入参数。输出参数通常用于从 存储过程获取值。输出参数使用起来比输入参数要复杂一些,当绑定一个给定的输出参数时,必须知道该参数的长度。如果为参数绑定的值大于您建议的长度,那么就会产生错误。


你可能感兴趣的:(开放数据库互连(Open Database Connectivity,ODBC) 与PDO 事务的四个特征 XSS)