【转】PHP PDO 学习笔记

一名新 PHP 数据对象 (PDOState of Qatar数据抽象层的原来开垦人士为您简单介绍该抽象层,入眼呈报与 Oracle
一齐运营的事态。

■PDO为何物?

PHP5中PDO的入门教程

亟需 PHP:5.0须要别的:Oracle 8 或更加高版本客商端库下载用于 Oracle 的 PDO
(WindowsState of Qatar:php_pdo.dll, php_pdo_oci.dll下载用于 Oracle 的 PDO
(Unix卡塔尔(قطر‎:pdo, pdo_oci

POD(PHP Data
Object)扩展在PHP5中加入,PHP6上校暗许知用PDO连接数据库,全体非PDO扩展将会在PHP6被从扩张中移除。该扩张提供PHP内置类
PDO来对数据库举行拜访,分化数据库使用近似的方式名,化解数据库连接不联合的主题材料。

举个例子已经了然了PDO,能够直接看下边的ThinkPHP
3.1怎么着行使PDO查询Mysql来幸免SQL注入风险。

PDO 简介

作者是安顿在windows下做开拓用的。

PDO(PHP Data Object卡塔尔国 是PHP 5新出来的东西,在PHP
5.5中,更是猛烈推荐使用PDO来管理数据库,将把全部的数据库扩大移到了PECL,那么暗中同意就是未有了作者们保养的php_mysql.dll之类的了,这如何做捏,大家惟有与时俱进了,笔者就小规模试制了一把PDO。

PHP
重若是由志愿者成功的品类;即便有少数部分一定的“宗旨”开辟人士,可是大家并未有一人在全职受薪的付出
PHP。除了那一个之外,大家分别坐落于世界区别地点,您能够虚构长时间开拓的和谐职业是什么样劳累。因而,PHP
主假诺依据非分之想的私有长时间须求来发展的,其缘由也巨细无遗,有的是试验,有的则是因为“今日有活要交”。即便那样平日每一步都会改过PHP,但从持久来看则是缺点和失误完整性 - 数据库扩展正是一个主要的事例。

■PDO的目标

【PDO是啥】

在各类区别的数目增加之间历来未曾当真的一致性,以致在有个别情况下,在此些增添内部也尚未真的的一致性。差相当少全数这几个扩大都在动用与根基数据库
API
紧凑相连的差别代码完毕着平等等级次序的职分。并且因为我们的人手很简单,因而那就招致了代码越发不便保证,进而为
PHP 带给了超大的难点。

提供一种轻型、清晰、方便的 API

PDO是PHP5新投入的多个至关心尊敬要意义,因为在PHP5此前的PHP4/PHP3都以一群的数据库扩张来跟种种数据库的接连和拍卖,什么
php_mysql.dll、php_pgsql.dll、php_mssql.dll、php_sqlite.dll等等扩大来三番五次MySQL、PostgreSQL、MS
SQL Server、SQLite,同样的,我们必须要依靠ADOdb、PEAGL450::DB、PHPlib::DB之类的数据库抽象类来援助大家,无比繁缛和低效,究竟,PHP代码的效用怎可以够比大家直接用C/C++写的恢弘斜率高捏?所以嘛,PDO的面世是必定的,我们要安静学习的心气去领受使用,恐怕你会开掘能够裁减你不菲武术哦。

鉴于 PHP 越来越受接待并再三成功,因而入眼 PHP
数据库扩张的拥护者们参与了在德意志举行的 LinuxTag 2002大会,在会上大家沟通了对 PHP 前景的观念。在研究 PHP
发展的随机性时,大家规定了在 PHP 中打开数据库访问的局地目的:

联合种种区别 LANDDBMS
库的共有本性,但不解除更高端的性状。

【安装PDO】

・提供一种轻型、清晰、方便的 API ・统一各样差异 奥迪Q5DBMS
库的共有特性,但不消逝更加高档的性状。 ・通过 PHP
脚本提供可选的比较大程度的空洞/宽容性。

由此 PHP
脚本提供可选的相当的大程度的虚幻/包容性。 

自个儿是在Windows XP SP2
下边,所以嘛,整个进度都是在Windows行实行的啦,至于Linux/FreeBSD
等平台,请自行检索资料设置安装。

笔者们由此提议了这种 PHP 数据对象 (PDO卡塔尔(قطر‎ 的定义,是因为大家期望通过应用
Zend Engine 2进取的面向对象天性获得该 API 的有的更理想的性质。

■PDO的特点:

自身的是PHP
5.4.31,已经自带有了php_pdo.dll的扩展,然而供给多少设置一下能力动用。

PHP 中的数据抽象层概念一点都不能算新;在 Google 中查询“PHP database
abstraction”会找到大致 83,200 个匹配项。它大致是数不胜数 PHP
开辟职员没世不忘的,而其产生则有的归因于大家残缺的
API。假如您已经尝试过使用第三方抽象层来完成别的真正关键的做事,平时会意识那个抽象层对于手头的办事来讲设计的效率过于强盛了

也许表现为在接受前需求开展大批量学学,大概变现为接口速度迟滞,参数必要经过多层脚本函数调用工夫达到数据库自有的
API;经常是存在上述二种表象。

本性。PDO
从一同首就吸收了现存数据库扩充成功和倒闭的经验训导。因为 PDO
的代码是全新的,所以大家有机遇再次最早规划性子,以利用 PHP 5
的新颖天性。

打开 c:windowsphp.ini ,那是自己的PHP配置文件,找到上边那行:

何以那个抽象层会存在这里种主题材料?那么些抽象层总是在试图完毕太多的任务,以致大概是不恐怕的天职。大家决定以实用为对象,仅将部分最布满的数据库
API 性子作为我们的幼功,并使得 PDO
驱动程序能够将它们特定于成品的风味暴光为常规扩张函数。

力量。PDO
意在将周围的数据库功用作为底蕴提供,同期提供对于 EnclaveDBMS
独特功能的方便访谈。

extension_dir

为什么使用 PDO?

轻松易行。PDO 意在让你能够轻巧使用数据库。API
不会暴虐参预您的代码,同期会清楚地方统一规范明各样函数调用的进度。

以此便是咱们扩展存在的目录,小编的PHP
5扩充是在:C:php5ext,那么本人就把那行改成:

听过有关数据库抽象扩充谣传的比超多人会应声对 PDO 的强大方面爆发困惑 -
大家是不是要解析 SQL,将其转移为相应的后端方言呢?大家什么管理性子 X
或特色 Y,等等。由此,当你听别人说大家在 PDO
中常常有毫无为此而令人担心时或然会吃惊;我们不指望使全数情节都统统统一,因为要使得这种统一改为恐怕,只好是将和睦节制在低于的通用规范。

运营时可扩展。PDO
增添是模块化的,让你能够在运作时为您的数据库后端加载驱动程序,而不须求再次编写翻译或重新安装整个
PHP 程序。比如,PDO_OCI 扩张会替代 PDO 扩大落成 Oracle 数据库
API。还会有部分用于 MySQL、PostgreSQL、ODBC 和 Firebird
的驱动程序,越来越多的驱动程序尚在付出。

    extension_dir = “C:/php5/ext”

万一 PDO 不是三个平安无事的抽象层,那还应该有啥样其他原因值得你思谋选拔它呢?

■安装PDO
自身这里是WINDOWS下支付用的PDO扩大,要是你要在Linux下安装配置,请到其余地方找寻。
本子要求:

然后再往php.ini上面找到:

・品质。PDO 从一初阶就摄取了现成数据库扩充成功和败北的资历训导。因为 PDO
的代码是崭新的,所以大家有机缘再一次起始规划本性,以利用 PHP 5
的最新天性。 ・才干。PDO
目的在于将大规模的数据库功效作为底工提供,同时提供对于 HighlanderDBMS
独特功用的便利访谈。 ・轻便。PDO 意在使您能够轻便利用数据库。API
不会冷酷参加您的代码,同一时间会知晓地注脚各样函数调用的进度。
・运维时可增加。PDO
扩张是模块化的,使您能够在运作时为你的数据库后端加载驱动程序,而无需再一次编写翻译或重新安装整个
PHP 程序。比如,PDO_OCI 扩张会代表 PDO 扩张实现 Oracle 数据库
API。还应该有一部分用以 MySQL、PostgreSQL、ODBC 和 Firebird
的驱动程序,越来越多的驱动程序尚在支付。

php5.1以致之后版本的前后相继包里早就带了;

    ;;;;;;;;;;;;;;;;;;;;;;
    ; Dynamic Extensions ;
    ;;;;;;;;;;;;;;;;;;;;;;

您恐怕想打听 PDO 与其他常用的抽象层的自己检查自纠意况,举个例子 PEAPRADO DB 或
ADODB。不论在 API 方面依旧在性质方面,PDO
都比别的周围抽象层要轻型,可是关乎到在逐个数据库后端之间提供统一性方面,则不及那一个抽象层,比方用于拍卖大量可移植性难题的
PEA奇骏 MDB 2 抽象层。

php5.0.x则要到pecl.php.net下载,放到你的扩张库,正是PHP所在的文件夹的ext文件夹下;

下边有一批相仿 ;extension=php_mbstring.dll
的事物,这里正是PHP增添加载的布置了,大家再最终边增加上大家PDO的恢弘:

在哪儿能够拿走 PDO?

手册上说5.0事情发生前的版本不可能运维PDO扩大。

    extension=php_pdo.dll
    extension=php_pdo_mysql.dll
    extension=php_pdo_pgsql.dll
    extension=php_pdo_sqlite.dll
    extension=php_pdo_mssql.dll
    extension=php_pdo_odbc.dll
    extension=php_pdo_firebird.dll
    ;extension=php_pdo_oci8.dll

PDO 是透过 PECL,即 PHP 扩张库提供的。假使您在运作 Linux
计算机,请遵照下边的注明进行安装;稍后是在 Windows 上设置的详细音信。

 

各个PDO的驱动,能给加上的全给加上,可是后边的php_pdo_oci8.dll,因为本身从不安装Oralce数据库,所以未有这几个,就选拔分号注释掉它。然后重启大家的Web服务器,
IIS/Apache,小编的是IIS,嘿嘿,表轻慢笔者,在Windows上,轻易嘛。

请小心,PDO
及其驱动程序当前高居“阿尔法”状态;那就表示大家会见理保障未有主要劣点,不过该程序包功效并不完美

大家还要加上超级多功能。就算大家慰勉你测验该程序包,但是其实不引入在日前将其用来临蓐。

配置:
修正你的php.ini配置文件,使它帮衬pdo.(php.ini这一个事物未有弄懂的话,先弄精通,要改良调用你的phpinfo(卡塔尔(قطر‎函数所呈现的非常php.ini)

重启后,在大家Web服务器的文书档案目录下写一个phpinfo.php的公文,加上这个:

Unix/Linux 安装

<?php
phpinfo();
?>

假定您早前从未有过尝试过 PHP 5,则请花一点时刻来通读一下“音信”和种种评释。在
UNIX Computer上,您或然要安装或进步 libxml2;如果未有libxml2,“pear”程序包管理工科具就不或者运营,您安装 PDO
时就能够遇到不菲艰巨。获取 PHP 5,并将其编写翻译和装置。确认保证钦命的前缀不是
/usr/local/,那样它就不会与 PHP 4 安装爆发冲突了:

extension=php_pdo.dll前边的支行去掉,分毫是php配置文件注释符号,这一个扩大是必需的。

在浏览器里面输入:

% ./configure –prefix=/usr/local/php5 –with-zlib [这里钦定其余选项]%
make install

往下还大概有
;extension=php_pdo.dll
;extension=php_pdo_firebird.dll
;extension=php_pdo_informix.dll
;extension=php_pdo_mssql.dll
;extension=php_pdo_mysql.dll
;extension=php_pdo_oci.dll
;extension=php_pdo_oci8.dll
;extension=php_pdo_odbc.dll
;extension=php_pdo_pgsql.dll
;extension=php_pdo_sqlite.dll

出口的内容中,倘令你能够顺遂的看来:

于今您就足以接纳“pear”工具获得并安装 PDO 以至用于 PDO 的 Oracle
驱动程序了。因为 PDO 当前标志为 阿尔法,所以默许意况下 pear
工具不会下载该程序包。在该程序包名称后边增加后缀“-alpha”,文告该 pear
工具得以安装 阿尔法 版本:

各各扩充所对应的数据库是:

    PDO
    PDO support enabled
    PDO drivers  mysql, pgsql, sqlite, mssql, odbc, firebird  

% PATH=”/usr/local/php5/bin:$PATH”% pear install PDO-alpha

Driver name Supported databases
PDO_DBLIB FreeTDS / Microsoft SQL Server / Sybase
PDO_FIREBIRD Firebird/Interbase 6
PDO_INFORMIX IBM Informix Dynamic Server
PDO_MYSQL MySQL 3.x/4.x
PDO_OCI Oracle Call Interface
PDO_ODBC ODBC v3 (IBM DB2, unixODBC and win32 ODBC)
PDO_PGSQL PostgreSQL
PDO_SQLITE SQLite 3 and SQLite 2

这正是说,恭喜您安装成功了,不然请留神检查上面的步调。

你须求报告 PHP 从专项使用于 PHP 5 的 php.ini 文件加载 PDO
驱动程序。假若你使用的前缀与笔者动用的均等,PHP 则会在
/usr/local/php5/lib/php.ini 中追寻 php.ini 文件。向该公文中增加以下行:

您要接收哪个种类数据库,只要把相应的扩充前的评释符号”;”去掉就足以了。

 

extension=pdo.so

使用PDO
本人那边假诺你早就装好mysql了,要是没装的话,麻烦先想方法装上,笔者的是mysql5.0.22,黑夜路人用的是MySQL
4.0.26也足以用。

【牛刀小小规模试制验】

现行反革命您须求获得数据库特定的驱动程序;对于 Oracle,此特定程序名为PDO_OCI。在 shell 中,键入:

数据库的连天: 我们透过上面包车型大巴例证来深入分析PDO连接数据库,

本人用的是MySQL
5.5.25a,假使您未曾设置MySQL,请自行安装。大家树立好了MySQL,何况在test库里增多了表foo,包括id,name,gender,time等多少个字段。

% pear install PDO_OCI-alpha

<?php$dbms='mysql';     //数据库类型 Oracle 用ODI,对于开发者来说,使用不同的数据库,只要改这个,不用记住那么多的函数了$host='localhost'; //数据库主机名$dbName='test';    //使用的数据库$user='root';      //数据库连接用户名$pass='';          //对应的密码$dsn="$dbms:host=$host;dbname=$dbName";//try {    $dbh = new PDO($dsn, $user, $pass); //初始化一个PDO对象,就是创建了数据库连接对象$dbh    echo "连接成功<br/>";    /*你还可以进行一次搜索操作

     foreach ($dbh->query('SELECT * from FOO') as $row) {        print_r($row); //你可以用 echo($GLOBAL); 来看到这些值    }    */    $dbh = null;} catch (PDOException $e) {    die ("Error!: " . $e->getMessage() . "<br/>");}//默认这个不是长连接,如果需要数据库长连接,需要最后加一个参数:array(PDO::ATTR_PERSISTENT => true) 变成这样:$db = new PDO($dsn, $user, $pass, array(PDO::ATTR_PERSISTENT => true));?>

大家伊始协会第一个PDO应用,创设二个pdo.php文件在Web文书档案目录下:

此驱动程序也亟需从 php.ini 文件加载;将下行加多到前边增添的那行之后:

数据库查询:
上面大家曾经实行了一回查询,大家还能利用如下的询问:

<?php
$dsn = "mysql:host=localhost;dbname=test";
$db = new PDO($dsn, 'root', '123456');
$count = $db->exec("INSERT INTO foo SET name = 'heiyeluren',gender='男',time=NOW()");
echo $count;
$db = null;
?>

extension=pdo_oci.so

<?php$db->setAttribute(PDO::ATTR_CASE, PDO::CASE_UPPER); //设置属性$rs = $db->query("SELECT * FROM foo");$rs->setFetchMode(PDO::FETCH_ASSOC);$result_arr = $rs->fetchAll();print_r($result_arr);?>

不知情啥意思,我们来逐步讲讲。那行:

今昔检查一下,确认保证它亦可运行:

以上因为用到setAttribute(卡塔尔国方法,放上那多个参数,把字段名强迫调换来大写。上面列出多有PDO::setAttribute(卡塔尔(قطر‎的参数:

$dsn = “mysql:host=localhost;dbname=test”;

% php -m

  • PDO::ATTR_CASE: 免强列名造成一种格式,详细如下(第一个参数卡塔尔(قطر‎:

    • PDO::CASE_LOWER: 强迫列名是小写.

    • PDO::CASE_NATURAL: 列名依据原有的主意

    • PDO::CASE_UPPER: 强逼列名称叫大写.

  • PDO::ATTR_ERRMODE: 错误提醒.

    • PDO::ERRMODE_SILENT: 不显得错误信息,只展现错误码.

    • PDO::ERRMODE_WARNING: 展现警报错误.

    • PDO::ERRMODE_EXCEPTION: 抛出非凡.

  • PDO::ATTR_ORACLE_NULLS (不止是ORACLE有效,别的数据库也一蹴而就State of Qatar:
    )内定数据库重回的NULL值在php中对应的数值。

    • PDO::NULL_NATURAL: 不变.

    • PDO::NULL_EMPTY_STRING: Empty string is converted to NULL.

    • PDO::NULL_TO_STRING: NULL is converted to an empty string.

  • PDO::ATTR_STRINGIFY_FETCHES: Convert numeric values to strings
    when fetching. Requires bool.

  • PDO::ATTR_STATEMENT_CLASS: Set user-supplied statement class
    derived from PDOStatement. Cannot be used with persistent PDO
    instances.
    Requires array(string classname, array(mixed constructor_args)).

  • PDO::ATTR_AUTOCOMMIT (available in OCI, Firebird and MySQL):
    Whether to autocommit every single statement.

  • PDO::MYSQL_ATTR_USE_BUFFERED_QUERY (available in MySQL): Use
    buffered queries.

正是构造我们的DSN(数据源),看看当中的信息包罗:数据库类型是mysql,主机地址是localhost,数据库名称是test,就那样多少个音讯。不相同数据库的数量源布局方式是不周边的。

在模块列表中,您应该拜会到 PDO 和 PDO_OCI。

澳门新浦京8455com,事例中的$rs->setFetchMode(PDO::FETCH_ASSOC卡塔尔(قطر‎;是PDOStatement::setFetchMode(卡塔尔国,对回到类型的宣示。
有如下:
PDO::FETCH_ASSOC — 关联数组情势
PDO::FETCH_NUM   — 数字索引数组方式
PDO::FETCH_BOTH  — 两个数组格局都有,那是缺省的
PDO::FETCH_OBJ   — 依据目的的款型,雷同于从前的
mysql_fetch_object()

$db = new PDO($dsn, ‘root’, ‘123456’);

防火墙碍事了?

越多重回类型申明(PDOStatement::方法名卡塔尔国看手册。

开端化一个PDO对象,构造函数的参数第一个就是大家的数据源,第四个是连接数据库服务器的客户,第四个参数是密码。大家不可能保险连接成功,前面我们会讲到极度情形,这里大家暂时感觉它是接连成功的。

倘诺您身处防火墙的前边,则在运用 pear
安装程序获取程序包时恐怕会遇见有些主题素材。假设发生这种气象,则可以遵照下列表明手动下载并设置这个程序包:

★插入,更新,删除数据,

$count = $db->exec(“INSERT INTO foo SET name =
‘heiyeluren’,gender=’男’,time=NOW()”);
echo $count;

% wget % pear install PDO-0.1.1.tgz

$db->exec("DELETE FROM `xxxx_menu` where mid=43");

调用我们总是成功的PDO对象来推行一个查询,那几个查询是一个布署一条记下的操作,使用PDO::exec(卡塔尔(قطر‎方法会重临三个影响记录的结果,所以大家输出这一个结果。最终依旧须求收尾对象财富:

[ 将 extension=pdo.so 添加到 php.ini ]

简轻易单的总括一下地点的操作:

$db = null;

% wget _OCI% pear install PDO_OCI-0.1.tgz

查询操作首倘诺PDO::query(State of Qatar、PDO::exec(State of Qatar、PDO::prepare(State of Qatar。
PDO::query(State of Qatar首要是用来有记录结果再次来到的操作,特别是SELECT操作,
PDO::exec(卡塔尔重倘使对准未有结果会集重返的操作,譬如INSERT、UPDATE、DELETE等操作,它回到的结果是眼前操作影响的列数。
PDO::prepare(State of Qatar重要是预管理操作,须要经过$rs->execute(State of Qatar来实施预管理内部的SQL语句,那么些法子能够绑定参数,效能比较强硬,不是本文能够轻易说精晓的,大家能够仿效手册和任何文档。

私下认可这几个不是长连接,假设急需多少库长连接,须求最后加三个参数:array(PDO::ATTGL450_PELANDSISTENT
=> true卡塔尔(قطر‎ 酿成那样:

[ 将 extension=pdo_oci.so 添加到 php.ini ]

获取结果集操作首倘诺:PDOStatement::fetchColumn(卡塔尔(قطر‎、PDOStatement::fetch(卡塔尔、PDOStatement::fetchALL(卡塔尔(قطر‎。
PDOStatement::fetchColumn(卡塔尔国 是获取结果钦命第一条记下的某部字段,缺省是第三个字段。
PDOStatement::fetch(卡塔尔国 是用来获取一条记下,
PDOStatement::fetchAll(State of Qatar是获得具备记录集到二个中,获取结果能够透过PDOStatement::setFetchMode来设置须求结果集结的种类。

$db = new PDO($dsn, ‘root’, ”, array(PDO::ATTR_PERSISTENT =>
true));

在上述二种情景下,都亟待首先调用“pear
install”;上述示范中的版本号在本文编写之时是风尚的,但随着开拓的接轨张开会发生变化。

除此以外有八个数见不鲜的操作,叁个是PDO::lastInsertId(卡塔尔国和PDOStatement::rowCount(卡塔尔(قطر‎。PDO::lastInsertId(卡塔尔(قطر‎是回来上次布置操作,主键列类型是自增的结尾的自增ID。
PDOStatement::rowCount(State of Qatar首若是用以PDO::query(卡塔尔国和PDO::prepare(卡塔尔国实行DELETE、INSERT、UPDATE操作影响的结果集,对PDO::exec(卡塔尔(قطر‎方法和SELECT操作无效。

三回操作就那样轻便,大概跟原先的远非太大分别,跟ADOdb倒是有几分相近。

Windows 安装

思想政治工作和自行提交

 
【继续刺探】

假定你正在运行 Windows,则请依照下列表达实行:

    至此,您曾经因此 PDO 连接到了 mysql,在发出查询早前,您应该知道 PDO
是何许保管专门的学业的。若是以前未有接触过事情,那么首先要明了事情的 4
个特点:原子性(Atomicity)、一致性(Consistency)、独立性(Isolation)和持久性(Durability),即
ACID。用外行人的话说,对于在多个事务中实行的其它职业,即便它是分等第实施的,也迟早能够保证该专门的学业会安全地运用于数据库,何况在劳作被交付时,不
会受到来自别的连接的震慑。事务性职业得以依赖哀告自动撤废(就算你尚未提交它),那使得脚本中的错误管理变得特别轻易。
   
事务平常是因此把一群修改储蓄起来、使之同不常间生效而落实的。那样做的益处是可以大大提升那么些创新的频率。换句话说,事务能够使脚本越来越快,况且恐怕更强壮(然则供给准确地应用专门的学问本事获得那样的平价)。 
   
不幸的是,实际不是每一个数据库都扶持专门的学问(Mysql5辅助专门的工作,mysql4自己不清楚卡塔尔,所以当第贰次展开连接时,PDO
供给在所谓的“自动提交(auto-commit)”情势下运作。自动提交格局表示,假如数据库支持职业,那么您所运营的每三个查询皆有它和睦的隐式事
务,假若数据库不帮忙工作,各种查询就未有那样的事情。假如您需求二个作业,那么必需利用
PDO::beginTransaction(卡塔尔(قطر‎方法来运维叁个事务。假若底层驱动程序不援救职业,那么将会抛出一个PDOException(无论错误处理设置是什么的:那总是叁个严重错误状态)。在贰个职业中,能够行使
PDO::commit(卡塔尔国 或 PDO::rollBack(卡塔尔(قطر‎来收场该事务,那取决事务中运作的代码是还是不是中标。
   
当脚本甘休时,恐怕当叁个三番五次就要被关门时,固然有一个未到位的事体,那么
PDO
将机关回滚该业务。那是一种安全措施,有利于防止在剧本非符合规律截止时出现不均等的情况——
若无显式地付出业务,那么假若有某些地点会并发不相仿,所以要实践回滚,以保证数据的安全性。

设若大家想提取数据的话,那么就应该运用数据得到功用。(上面用到的$db都以上边已经三番两次好的靶子)

・从 #v5 获取 PHP 5,将其解压缩到 C:/php5。 ・从 _5_0/php_pdo.dll
和_5_0/php_pdo_oci.dll 分别赢得 PDO 和 PDO_OCI,将其归入C:/php5/ext。可能,您能够从 PHP 5 下载页上列出的“用于 PHP 5.0.0 的 PECL
模块群集”zip 文件中找到全部这一个 PDO 驱动程序,以至具备 PECL 程序包的兼具
Windows 版本。 ・编辑 C:/php5/php.ini 文件,并加上下列内容:

//例子来自http://www.ibm.com/developerworks/cn/db2/library/techarticles/dm-0505furlong/index.htmltry {  $dbh = new PDO('odbc:SAMPLE', 'db2inst1', 'ibmdb2',       array(PDO_ATTR_PERSISTENT => true));  echo "Connectedn";  $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();}

<?php
foreach ($db->query("SELECT * FROM foo") as $row)
{
    print_r($row);
}
?>

extension=php_pdo.dllextension=php_pdo_oci.dll

在地点的身体力行中,若是大家为七个新雇员创造一组条目款项,这一个雇员有二个 ID
号,即
23。除了输入此人的大旨数据外,我们还供给记录雇员的薪俸。五个立异分别产生起来异常的粗略,但透过将那八个立异包罗在
beginTransaction(卡塔尔(قطر‎ 和 commit(State of Qatar调用中,就能够保证在改变实现早前,别的人不能见到更动。假诺爆发了错误,catch
块能够回滚事务开端以来发出的有所改造,并打字与印刷出一条错误音讯。

咱俩也能够接纳这种获取方式:

编排 php.ini 文件时,有少数很首要,即要在此外其它 PDO 驱动程序在此以前先加载
PDO 扩大,不然就不能够正确开端化。

实际不是应当要在专门的学业中作出更新。您也足以生出复杂的查询来领取数额,还是能选取这种消息营造越来越多的换代和查询。当工作在移动时,能够确定保证别的人在干活扩充在那之中无法作出变动。事实上,那不是
100% 的不错,但要是你以前从未耳闻过业务的话,那样介绍也未尝不可。

<?php
$rs = $db->query("SELECT * FROM foo");
while ($row = $rs->fetch())
{
    print_r($row);
}
?>

一经在 Windows 目录中有一个 PHP 4 的大局 php.ini
文件,则也许会蒙受标题。最佳的缓慢解决格局是,移动该 php.ini 文件,使其与
PHP 4 SAPI 坐落于同一的文件夹中,以砍断 PHP 4 安装;举个例子,将其活动到与
php4apache.dll 相通的文本夹中。请留意,PHP 5
主次中不用全部文书档案都是时尚的;推荐的设置进程如下边所述 - 如 install.txt
文件所评释的,请勿将其他 DLL 复制到 windows 文件夹或 system 文件夹中 -
任何内容都以自包括的。纵然你运转的是 apache,何况境遇不可能加载 DLL
的荒唐,则检查一下是或不是将 C:/php5 增添到了 PATH 中。别的,还要小心 PHP 5
的 CGI 版本今后的称呼为 php-cgi.exe。

预管理语句和仓库储存进程

假若想二次把多少都得到到数组里能够如此:

连接 PDO

超多更成熟的数据库都扶持预管理语句的定义。什么是预管理语句?您能够把预管理语句看作您想要运行的
SQL
的一种编写翻译过的模版,它能够选取变量参数实行定制。预管理语句能够带给两大好处:

<?php
$rs = $db->query("SELECT * FROM foo");
$result_arr = $rs->fetchAll();
print_r($result_arr);
?>

率先创立 PDO
类的多个实例,将其看做数据库句柄。使用哪个基本功驱动程序并不重大;您总要使用
PDO 类名。布局函数的第二个参数为数量源名称
(DSN卡塔尔,第3个参数为客商名,第八个参数为该顾客名的口令。DSN 的 PDO
命名惯例为 PDO
驱动程序的名号,前边多个冒号,再前面是可选的驱动程序特定的新闻。在大家的身教重于言教中,会加载
OCI
驱动程序但不钦赐其余其余音讯;那样会选择暗中认可的数据库。对于别的驱动程序,如
ODBC 驱动程序,第五个冒号后边的有所内容都将被充任 ODBC DSN。MySQL
驱动程序会相符以分歧的点子批注它的 DSN。

  • 询问只需剖判(或希图)壹次,可是可以用平等或不相同的参数实践数十次。当查问策动好后,数据库将分析、编写翻译和优化试行该查询的安顿。对于复杂的查
    询,那个历程要花比较长的岁月,假若您须求以分裂参数多次重复相像的询问,那么该进度将大大减弱应用程序的进程。通过动用预管理语句,能够制止双重深入分析/
    编写翻译/优化周期。简言之,预管理语句使用越来越少的财富,由此运营得更加快。
  • 提须求预管理语句的参数没有必要用引号括起来,驱动程序会管理那几个。假若应用程序独自据有地使用预管理语句,那么能够保障未有SQL
    侵犯产生。(然则,如若您照旧将查询的别的界分创设在不受信赖的输入之上,那么就照样存在高风险)。

输出:

万一不能够加载该驱动程序,只怕产生了连年退步,则会抛出三个PDOException,以便你能够调控哪些最棒地管理该故障。

预管理语句是那样有用,引致 PDO 实际上打破了在目的 4
中设下的平整:假设驱动程序不扶植预管理语句,那么 PDO
将仿真预处理语句。 

Array
(
    [0] => Array
        (
            [id] => 1
            [0] => 1
            [name] => heiyeluren
            [1] => heiyeluren
            [gender] => 男
            [2] => 男
            [time] => 2006-10-28 23:14:23
            [3] => 2006-10-28 23:14:23
        )
}

?phptry {$dbh = new PDO(“OCI:”, “scott”, “tiger”);} catch (PDOException
$e) {echo “Failed to obtain database handle ” .$e-getMessage(); }?

实例:PDO的采用例子:

小编们相中间的笔录,数字索引和关联索引都有,浪费资源,我们只要求关联索引的:

在一连字符串中,您能够钦定多个可选参数;第二个是数据库名称,第二个是字符集;那几个参数与可选的第八个和第八个参数相对应,后多少个参数您或然在
oci8 扩大函数 ociconnect(State of Qatar 或 ocipLogon(卡塔尔国中选择过。要接收一定的字符集连接贰个特定的数据库,则足以实践下列操作:

<?php$dbms='mysql'; //数据库类型 Oracle 用ODI,对于开发者来说,使用不同的数据库,只要改这个,不用记住那么多的函数了$host='localhost'; //数据库主机名$dbName='test'; //使用的数据库$user='root'; //数据库连接用户名$pass=''; //对应的密码$dsn="$dbms:host=$host;dbname=$dbName"; class db extends PDO {    public function __construct(){        try {            parent::__construct("$GLOBALS[dsn]", $GLOBALS['user'], $GLOBALS['pass']);         } catch (PDOException $e) {         die("Error: " . $e->__toString() . "<br/>");        }    }        public final function query($sql){        try {            return parent::query($this->setString($sql));        }catch (PDOException $e){            die("Error: " . $e->__toString() . "<br/>");        }    }        private final function setString($sql){        echo "我要处理一下$sql";        return $sql;    }}$db=new db();$db->setAttribute(PDO::ATTR_CASE, PDO::CASE_UPPER);foreach ($db->query('SELECT * from xxxx_menu') as $row) {    print_r($row);}$db->exec('DELETE FROM  `xxxx_menu` where mid=43');?>

<?php
$db->setAttribute(PDO::ATTR_CASE, PDO::CASE_UPPER);
$rs = $db->query("SELECT * FROM foo");
$rs->setFetchMode(PDO::FETCH_ASSOC);
$result_arr = $rs->fetchAll();
print_r($result_arr);
?>

?phptry {$dbh = new PDO(“OCI:dbname=accounts;charset=UTF-8”, “scott”,
“tiger”);} catch (PDOException $e) {echo “Failed to obtain database
handle ” .$e-getMessage(); }?

参考:
1.
2.
3. 
4.PHP手册

看上边的代码,setAttribute(卡塔尔方法是设置有个别属性,首要品质有:PDO::ATT讴歌RDX_CASE、PDO::ATTR_EWranglerRMODE等等,大家这里须要安装的是PDO::ATTR_CASE,正是大家运用关联索引获取数据集的时候,关联索引是大写依旧小写,有多少个筛选:

简易 try..catch
调控构造并无益处。若是在应用程序的较高端别未有概念特别管理,则在不或许创立数据库连接的场所下,该脚本会终止。

source url:

    PDO::CASE_LOWEEscort — 强逼列名是小写
    PDO::CASE_NATURAL — 列名遵照原本的不二等秘书籍
    PDO::CASE_UPPE途睿欧 — 抑遏列名字为大写

连续几天管理

笔者们利用setFetchMode方法来设置获取结果集的再次回到值的花色,一样类型还应该有:

近来,PDO 完全未有奉行本身的其它连接处理,由此每一个“新
PDO”调用都会确立二个新的数据库连接。该连接在 $dbh
变量越界时,大概当您为其钦赐 NULL 值时会被保释。

    PDO::FETCH_ASSOC — 关联数组方式
    PDO::FETCH_NUM — 数字索引数组情势
    PDO::FETCH_BOTH — 两个数组格局都有,那是缺省的
    PDO::FETCH_OBJ — 根据指标的情势,相像于早先的
mysql_fetch_object()

?phptry {$dbh = new PDO(“OCI:dbname=accounts;charset=UTF-8”, “scott”,
“tiger”卡塔尔国;} catch (PDOException $e卡塔尔国 {echo “Failed to obtain database
handle ” .$e-getMessage(卡塔尔国;exit; }// 在这里处对数据库实施一些操作 // …//
现在产生,释放该连接$dbh = null;?

本来,平日景象下我们是接受PDO::FETCH_ASSOC,具体运用什么,依据你本人的急需,其余获取项目参考手册。

铺排在不久的前几天为 PDO 增添连接缓存成效;就现阶段的 oci8
扩充来说,会援引与存活服务器的一连,而且在此些连接中,还大概会引用闲置的报到。当在缓存连接方式中运作时,如上边的代码段所示释放
$dbh 时会将该登入标志为可由别的连接重用。

除却上面这种获取数据的方式,还应该有这种:

假如您使用 ODBC 驱动程序访谈 Oracle,则恐怕会很欢愉地小心到,默许情状下
PDO_ODBC 驱动程序扶持 ODBC 连接池。

<?php
$rs = $db->prepare("SELECT * FROM foo");
$rs->execute();
while ($row = $rs->fetch())
{
    print_r($row);
}
?>

使用 PDO

实则大概啦。假若您想得到钦命记录里叁个字段结果的话,能够采取PDOStatement::fetchColumn(卡塔尔(قطر‎:

问询几个编制程序 API
的最棒办法便是利用它,因此大家来看一下附带的这几个演示,以询问怎样进展批次更新(代码如下卡塔尔(قطر‎。

<?php
$rs = $db->query("SELECT COUNT(*) FROM foo");
$col = $rs->fetchColumn();
echo $col;
?>

?php

诚如选用fetchColumn(卡塔尔(قطر‎来拓宽count总结或者有个别只要求单字段的笔录很好操作。

// Create a PDO database handle object// the ‘oci:’ string specifies
that the OCI driver should be used// you could use ‘oci:dbname=name’ to
specify the database name.// The second and third parameters are the
username and password respectively$dbh = new PDO(‘oci:’, ‘scott’,
‘tiger’);

 

// Create a test table to hold the data from
credits.csv$dbh-exec(“CREATE TABLE CREDITS (extension varchar(255),name
varchar(255))”);

一句话来说的下结论一下方面包车型地铁操作

// start a transaction$dbh-beginTransaction();

询问操作首倘诺PDO::query(卡塔尔国、PDO::exec(State of Qatar、PDO::prepare(State of Qatar。PDO::query(State of Qatar首假设用来有记录结果再次回到的操作,特别是SELECT操作,PDO::exec(State of Qatar首倘若照准未有结果群集重临的操作,譬喻INSERT、UPDATE、DELETE等操作,它回到的结果是当前操作影响的列数。PDO::prepare(State of Qatar首即使预管理操作,要求通过$rs->execute(卡塔尔来试行预管理之中的SQL语句,这一个形式能够绑定参数,成效比较强硬,不是本文能够轻巧说清楚的,大家能够参谋手册和别的文书档案。

// prepare to insert a large quantitiy of data$stmt =
$dbh-prepare(“INSERT INTO CREDITS (extension, name) VALUES (:extension,
:name)”);

赢得结果集操作首借使:PDOStatement::fetchColumn(State of Qatar、PDOStatement::fetch(卡塔尔、PDOStatement::fetchALL(State of Qatar。PDOStatement::fetchColumn(卡塔尔国是获得结果钦命第一条记下的某部字段,缺省是第多个字段。PDOStatement::fetch()是用来获得一条记下,PDOStatement::fetchAll(卡塔尔(قطر‎是获取具备记录集到叁个中,获取结果能够因此PDOStatement::setFetchMode来设置须要结果集合的体系。

// bind the inputs to php variables; specify that the data will be
strings// with a maximum length of 64
characters$stmt-bindParam(‘:extension’,$extension,PDO_PARAM_STR,
64);$stmt-bindParam(‘:name’, $name,PDO_PARAM_STR, 64);

别的有多少个不闻不问的操作,三个是PDO::lastInsertId(卡塔尔和PDOStatement::rowCount(卡塔尔(قطر‎。PDO::lastInsertId(State of Qatar是回到上次安顿操作,主键列类型是自增的末尾的自增ID。PDOStatement::rowCount(卡塔尔主固然用来PDO::query(State of Qatar和PDO::prepare(State of Qatar进行DELETE、INSERT、UPDATE操作影响的结果集,对PDO::exec(卡塔尔方法和SELECT操作无效。

// 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();

【错误管理】

?

一经程序中遇到错误咋做?我们那边描述PDO类的错误音信和丰裕管理。

既是大家早已打响总是到了
Oracle,那么未来就能够创制一个表来保存一些数额了。对于此示例,咱们运用部分
PHP 增添及其作者,并将那么些剧情输入叁个数据库中。数据库句柄对象的 exec()方法可用来发生不会回来结果集的比十分的快叁回性查询,因而大家在此边运用该形式来爆发CREATE TABLE 查询。

1、面向对象的点子

为了使得示例更自然,作者从 PHP
源代码中收取了扩充及其小编的音讯,并将其储存到了一个 CSV
文件中。那就象征多个广阔意况:从 CSV
文件批次导入数据。在大家的演示中,大家充足利用了 Oracle
的预管理语句和绑定参数,以获取一个便捷的数据导入脚本。在叙述该示例早前,有必要精晓一下
PDO 处总管务的措施。

先看看假若一连错误等的拍卖,使用面向对象的点子来拍卖:

PDO 中的事务管理

<?php
try
{
    $db = new PDO('mysql:host=localhost;dbname=test', $user, $pass);
    $db = null;
}
catch (PDOException $e)
{
    print "Error: " . $e->getMessage() . "<br/>";
    die();
}
?>

Oracle
具有三个机警的暗中同意操作形式:当您进行一而再三回九转时,将会放在多个隐式事务管理中,在交付业务以前在那之中的更换不会完全奏效。除了事务管理的规范优点之外,数据库服务器在执行每回换代之后还无需再行创设索引和此外内部布局;它可以延迟到提交现在進展。这样会加快代码的推行。Oracle
那一点真正很好。

此地运用大家PHP
5面向对象的特别管理特征,若是内部有不行的话就开始化调用PDOException来最初化二个十三分类。

但不幸的是,并不是各样数据库经销商都帮助事务管理,并且因为 PDO
意在以一种相对可移植的章程扶持这一个事务管理,所以它暗中同意景况下以电动提交情势运转。启用自动提交格局后,数据库驱动程序会隐式提交每一个成功的立异。当你调用
$dbh-beginTransaction(State of Qatar 时,就可以呈请关闭自动提交,直到调用 $dbh-commit(卡塔尔国只怕 $dbh-rollBack(卡塔尔(قطر‎才会再一次启用,具体决定于你的代码是怎样编写的。假使幼功驱动程序不帮衬事务管理,则会抛出一个PDOException。

PDOException非常类的习性构造

万第一行当生了难题还要 PHP
出错,您的剧本将脱离并且作业处于待批状态;可能你关闭数据库句柄时,PDO
会自动针对其余待批的政工资调度用
$dbh-rollBack(State of Qatar。此行为会减弱向数据库中提交恐怕未定义大概已破坏数据的恐怕,那是用来拍卖已废弃专业的正式语义。

<?php
class PDOException extends Exception
{
    public $errorInfo = null;    // 错误信息,可以调用 PDO::errorInfo() 或 PDOStatement::errorInfo()来访问
    protected $message;            // 异常信息,可以试用 Exception::getMessage() 来访问
    protected $code;            // SQL状态错误代码,可以使用 Exception::getCode() 来访问
}
?>

预管理语句、存款和储蓄进程

以此极其管理类是集成PHP 5内置的不行处理类,大家大约的看一下PHP
5内置的可怜管理类组织:

PDO 补助接收 Oracle 样式命名的占位符语法将变量帮定到 SQL
中的预管理语句。PDO
还为别的数据库提供了命名占位符模拟,以致足认为生来就不援救该概念的数据库模拟预管理语句和绑定参数。那是
PHP 向前迈进的积极一步,因为那样能够使开辟职员能够用 PHP
编写“公司级”的数据库应用程序,而不要专程关爱数据库平台的本事。

<?php
class Exception
{
    // 属性
    protected $message = 'Unknown exception';   // 异常信息
    protected $code = 0;                        // 用户自定义异常代码
    protected $file;                            // 发生异常的文件名
    protected $line;                            // 发生异常的代码行号
    // 方法
    final function getMessage();                // 返回异常信息
    final function getCode();                   // 返回异常代码
    final function getFile();                   // 返回发生异常的文件名
    final function getLine();                   // 返回发生异常的代码行号
    final function getTrace();                  // backtrace() 数组
    final function getTraceAsString();          // 已格成化成字符串的 getTrace() 信息
}
?>

应用 PDO 预管理语句特简单,调用数据库句柄的 prepare(卡塔尔国方法就能够。它会重回叁个言辞句柄对象,然后你能够动用该指标来绑定参数和实施语句。在这里示例中,大家将要定义三个命名占位符,“:extension”和“:name”,那五个占位符分别与
.CSV 文件中的 PHP 扩充名称和内部二个作者的姓名相对应。

相应的,在代码中得以符合的调用 getFile(卡塔尔国 和 getLine(卡塔尔来举行不当定位,更有利的进展调治将养。

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

2、使用面向进程的办法

预管理了讲话之后,我们选取 bindParam(卡塔尔国 方法来将这一个命名参数分别与 PHP
变量名称“$extension”和“$name”相关联。大家还恐怕会通报
Oracle,那个数据就要格式化为字符串,最大尺寸为 64 个字符。

先看代码:

$stmt-bindParam(‘:extension’, $extension, PDO_PARAM_STR,
64);$stmt-bindParam(‘:name’, $name, PDO_PARAM_STR, 64);

<?php
$db = new PDO('mysql:host=localhost;dbname=test', $user, $pass);
$rs = $db->query("SELECT aa,bb,cc FROM foo");
if ($db->errorCode() != '00000')
{
    print_r($db->errorInfo());
    exit;
}
$arr = $rs->fetchAll();
print_r($arr);
$db = null;
?>

大家明日即希图好插入数据了 - 大家只供给展开该 CSV
文件,并从当中获取数据就可以。通过采取 fopen(卡塔尔 和 fgetcsv(卡塔尔函数能够一定简单地成功此操作。然后,大家能够动用 PHP list(卡塔尔国布局函数直接将 CSV
的列钦赐给变量“$extension”和“$name”。因为那几个变量已经绑定到了语句中,所以大家明日要做的只是调用该语句对象的
execute(State of Qatar 方法使其推行插入。这种艺术既有援助又便捷 -
在事务管理时各样迭代循环独有两行。达到文件尾时,大家就足以即时采取数据库句柄的
commit(卡塔尔(قطر‎ 方法来交给那些退换了。

PDO和PDOStatement对象有 errorCode(State of Qatar 和 errorInfo(卡塔尔国方法,若无其他不当, errorCode(卡塔尔(قطر‎ 重临的是: 00000
,不然就能回去一些错误代码。errorInfo(卡塔尔(قطر‎再次来到的一个数组,饱含PHP定义的错误代码和MySQL的错误代码和错误新闻,数组布局如下:

如果您只是要传送输入参数,何况有众多那样的参数要传送,那么您会以为下边所示的神速形式语法非常常有帮扶;此语法使您可以节约对
$stmt-bindParam(卡塔尔(قطر‎ 的调用。

Array
(
    [0] => 42S22
    [1] => 1054
    [2] => Unknown column ‘aaa’ in ‘field list’
)

$stmt = $dbh-prepare(“INSERT INTO CREDITS (extension, name) VALUES
(:extension, :name)”);$stmt-execute(array(‘:extension’ = $extension,
‘:name’ = $name));

每一遍实行查询之后,errorCode()的结果都是风靡的,所以我们得以超级轻便自个儿说了算错误消息展现。

你还是能行使 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功效确实强盛,其余还会有局地剧情作者从未讲到,比方绑定参数、预管理、存款和储蓄进度、事务管理等等效用。其余还也可以有区别数额扩
DSN的组织,Oracle数据库本人许多特种的东西,都亟待深远去学学明白,那篇小说就只是轻松的叙说了一部分入门知识,算是对PDO多少个简便的理解吗。

利用 PDO
抓取数据与扩充插队或更新相通,只是你施行完询问之后,将在重复调用 fetch()方法来取得结果集的下一行。实行获取的最轻巧易市价况如下所示,值得注意的少数是,您还是能够将参数绑定到查询,以调节如
WHERE 子句那样的源委;实践此操作的语法与我们早已观看的 bindParam(卡塔尔代码完全相像。

【事务和机关提交】

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

 至此,您曾经由此 PDO 连接到了 mysql,在产生查询在此之前,您应该知道 PDO
是何许处总管务的。若是以前并未有接触过事情,那么首先要清楚事情的 4
个特征:原子性(Atomicity)、一致性(Consistency)、独立性(Isolation)和长久性(Durability),即
ACID。用外行人的话说,对于在一个职业中施行的别的工作,就算它是分等级推行的,也终将能够确认保障该专业会安全地选择于数据库,并且在做事被交付时,不会遭到来自此外总是的影响。事务性专门的学问能够依据诉求自动废除(借令你还向来不提交它),那使得脚本中的错误管理变得更其便于。

PDO
扶持部分不一的抓取计谋,那些安顿在方便性和总体性方面拥分化;通过将下列选项之一钦赐为
fetch(State of Qatar 方法的参数,您能够变动其重回值以适应您的语法:

业务平常是透过把一堆改进储蓄起来、使之同期生效而完成的。那样做的好处是足以大大升高那个立异的频率。换句话说,事务能够使脚本越来越快,并且只怕更强壮(然则需求科学地使用工作技术获得那样的实惠)。

・PDO_FETCH_NUM - 每一种行抓取再次来到一个遵守列地方索引的数组,并且以 0
为基数。

噩运的是,实际不是种种数据库都帮助职业(Mysql5支撑专门的学业,mysql4本身不亮堂卡塔尔国,所以当第壹回打开连接时,PDO
供给在所谓的“自动提交(auto-commit)”格局下运作。自动提交形式代表,假设数据库帮衬理工科程师作,那么你所运营的每叁个询问皆有它本人的隐式事务,若是数据库不辅助职业,各种查询就向来不比此的事务。如若你须求贰个职业,那么必需运用
PDO::beginTransaction(State of Qatar方法来运维叁个业务。假若底层驱动程序不支持职业,那么将会抛出一个PDOException(无论错误管理设置是怎么的:那总是一个严重错误状态)。在三个政工中,能够利用
PDO::commit(卡塔尔 或 PDO::rollBack(卡塔尔国来终止该事情,那决计于事务中运转的代码是或不是中标。

while ($row = $stmt-fetch(PDO_FETCH_NUM)) {printf(“Extension %s, by
%sbr”, $row[0], $row[1]);}

当脚本甘休时,或许当叁个连连就要被关门时,要是有一个未成功的事体,那么
PDO
将自行回滚该事务。那是一种安全措施,有利于幸免在剧本非不荒谬甘休时现身差别等的情状――
若无显式地付出业务,那么若是有有个别地点会并发不均等,所以要施行回滚,以保障数据的安全性。

・PDO_FETCH_ASSOC -
各个行抓取依照行集中的列名,再次回到叁个按列名索引的数组。

<?php
// 例子来自http://www.ibm.com/developerworks/cn/db2/library/techarticles/dm-0505furlong/index.html
try
{
    $db = new PDO('odbc:SAMPLE', 'db2inst1', 'ibmdb2', array(PDO_ATTR_PERSISTENT => true));
    echo "Connected\n";
    $db->setAttribute(PDO_ATTR_ERRMODE, PDO_ERRMODE_EXCEPTION);
    $db->beginTransaction();
    $db->exec("insert into staff (id, first, last) values (23, 'Joe', 'Bloggs')");
    $db->exec("insert into salarychange (id, amount, changedate) values (23, 50000, NOW())");
    $db->commit();
}
catch (Exception $e)
{
    $db->rollBack();
    echo "Failed: " . $e->getMessage();
}
?>

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

在上头的身教重于言教中,借使大家为贰个新雇员创制一组条约,这么些雇员有二个 ID
号,即
23。除了输入此人的中坚数据外,大家还亟需记录雇员的报酬。多个改正分别成功起来很简短,但透过将这七个立异包含在
beginTransaction(卡塔尔 和 commit(卡塔尔(قطر‎调用中,就能够保险在退换实现在此以前,其余人不能够看出改变。假若发生了错误,catch
块能够回滚事务开首以来发出的享有改动,并打字与印刷出一条错误消息。

・PDO_FETCH_BOTH -
每一种行抓取重回三个既遵循列地点又服从列名索引的数组。也便是上述二种情景的第一手组合。若无一点名抓取形式,则该形式为私下认可形式。
・PDO_FETCH_OBJ - 每一种行抓取再次来到多少个无名氏对象,其属性名与列名对应。

并非大势所趋要在业务中作出更新。您也能够生出复杂的询问来领取数额,仍可以使用这种新闻营造更加多的翻新和询问。当职业在移动时,能够保障别的人在做事進展此中不可能作出改换。事实上,那不是
100% 的不错,但万一您事情发生从前并未有据悉过业务的话,那样介绍也未尝不可。

while ($row = $stmt-fetch(PDO_FETCH_ASSOC)) {echo “Extension
{$row-EXTENSION} by {$row-NAME}br”;}

 

・PDO_FETCH_LAZY -
每种行抓取重回贰个援用语句对象的重载对象。那“看起来”好疑似PDO_FETCH_OBJ 和 PDO_FETCH_BOTH 的组合,只是独有当您在本子中做客 PHP
变量时才创制那个变量。 ・PDO_FETCH_BOUND - 抓取每行,返回TRUE。在使用绑定输出列时这种艺术特别有用,它能够制止成立没有必要的其余数组或对象。。

【预管理语句和仓库储存进度】

无论是你使用哪个种类抓取攻略,当没有其他行可抓取时,fetch(State of Qatar 方法将会回到
FALSE。

数不尽更成熟的数据库都扶持预管理语句的概念。什么是预管理语句?您能够把预管理语句看作您想要运转的
SQL
的一种编写翻译过的模板,它能够运用变量参数进行定制。预管理语句能够带给两大受益:

近来本身要叙述一些才能,如若您须要最后再调节一下剧脾性能的话,那几个工夫只怕会对您有所帮忙。但先给你一个忠告:要像逃匿瘟疫相像制止不成熟的优化。您应该总是首推最清楚、可维护性最棒的缓和方案。请牢牢记住,在二个卓越的
Web
应用程序中,您不能够衡量各类抓取方式间的界别,除非脚本要拍卖相当多行。作者再另行叁遍:抓取格局间的属性不相同相当的小- 请使用最符合你代码的情势。

   
查询只需剖析(或思索)三回,然而足以用同样或不相同的参数实施多次。当查问计划好后,数据库将解析、编写翻译和优化实施该查询的布置。对于复杂的询问,这几个进度要花相比较长的年华,假设你需求以分裂参数多次重复相仿的询问,那么该进程将大大减少应用程序的快慢。通过行使预管理语句,能够免止重复解析/
编写翻译/优化周期。简言之,预管理语句使用越来越少的财富,由此运维得越来越快。
   
提要求预管理语句的参数无需用引号括起来,驱动程序会管理这一个。要是应用程序独自据有地使用预管理语句,那么能够确定保障没有SQL
凌犯发生。(然则,假设您依旧将查询的别样一些建设构造在不受信赖的输入之上,那么就照样存在高风险)。

请记住,使用 PDO_FETCH_NUM
的开销非常的小,因为访谈列数据只是叁个简练的数值查询。PDO_FETCH_OBJ
让你能够接收 OO
语法将数据集的列作为对象的品质来做客,可是各样属性访谈都关涉一个附加的散列查询,使得应用它的支出基本上与
PDO_FETCH_ASSOC 相近。各样那样的方式都会复制整行,进而占用稍多的内部存款和储蓄器。

预管理语句是那样有用,导致 PDO 实际上打破了在对象 4
中设下的规规矩矩:假若驱动程序不帮衬预管理语句,那么 PDO
将仿真预处理语句。

比十分大多据库驱动程序都会代表你事情未发生前抓取并缓存一定数额的行。PHP
每一次访问在那之中二个那样行中的列时,它都亟需将其复制到本人的专项使用内部存款和储蓄器区域中。倘令你的询问涉及大多行,而只供给依照某种复杂的逻辑访谈给定行的特定列,则您会意识
PDO_FETCH_LAZY
是一种幸免使用过多内部存款和储蓄器的管用方法,因为它独有在你访谈给定列时才复制该列。使用此方式时要留心,从有些给定语句为各种fetch(卡塔尔抓取的“惰性对象”是历次迭代时使用的等同对象。那就暗暗提示着您不可能只是简短地蕴藏该指标用于现在的比较,因为它仍旧会引用该语句的当下行
- 您要求手动复制所要求的有的。

实例:PDO的行使例子:

最后一种格局为 PDO_FETCH_BOUND,该形式会告诉 PDO
您曾经将全部列绑定到了 PHP
变量,而且除了要它在达到行集的结尾时通报你外无需它实践其他任何操作。绑定输出列在概念上与绑定输入参数相同,只是绑定输出列能够用于全部数据库驱动程序。您能够将
PHP 变量绑定到命名列,PDO 将要历次调用 execute(卡塔尔国时对其实行修正。此本事可用来剃去结果聚焦每列、每行的有的虚构机器操作码。这种手艺的劣势在于,恐怕会使您的代码难以追踪,您使用变量名称时索要倍加小心。上边的代码表明了绑定输出列的行使。请留意,您不要指定PDO_FETCH_BOUND 就能够使用 $stmt-bindColumn(卡塔尔(قطر‎;PDO_FETCH_BOUND
只是一个对此你掌握只能动用绑定值的景况的一种优化。

<?php
$dbms = 'mysql';        // 数据库类型 Oracle 用ODI,对于开发者来说,使用不同的数据库,只要改这个,不用记住那么多的函数了
$host = 'localhost';    // 数据库主机名
$dbName = 'test';        // 使用的数据库
$user = 'root';            // 数据库连接用户名
$pass = '';                // 对应的密码
$dsn = "$dbms:host=$host;dbname=$dbName";
class db extends PDO
{
    public function __construct()
    {
        try
        {
            parent::__construct("$GLOBALS[dsn]", $GLOBALS['user'], $GLOBALS['pass']);
        }
        catch (PDOException $e)
        {
            die("Error: " . $e->__toString() . "<br/>");
        }
    }
    public final function query($sql)
    {
        try
        {
            return parent::query($this->setString($sql));
        }
        catch (PDOException $e)
        {
            die("Error: " . $e->__toString() . "<br/>");
        }
    }
    private final function setString($sql)
    {
        echo "我要处理一下$sql";
        return $sql;
    }
}
$db = newdb();
$db->setAttribute(PDO::ATTR_CASE, PDO::CASE_UPPER);
foreach ($db->query('SELECT * from xxxx_menu') as $row)
{
    print_r($row);
}
$db->exec('DELETE FROM  `xxxx_menu` where mid=43');
?>

$stmt = $dbh-prepare(“SELECT extension, name from CREDITS”);if
($stmt-execute()) {$stmt-bindColumn(‘EXTENSION’,
$extension);$stmt-bindColumn(‘NAME’, $name);while
($stmt-fetch(PDO_FETCH_BOUND)) {echo “Extension:$extension,
Author:$name/n”; }}

ThinkPHP 3.1如何运用PDO查询Mysql来制止SQL注入危害

可移植性

当大家选择守旧的 mysql_connect
、mysql_query方法来连接查询数据库时,假若过滤不严,就有SQL注入危害,以致网址被攻击,失去调节。即使能够用mysql_real_escape_string(卡塔尔函数过滤客商提交的值,可是也许有欠缺。而使用PHP的PDO增添的
prepare 方法,就足避防止 sql injection 危害。

区分抑扬顿挫写的列

PDO(PHP Data ObjectState of Qatar 是PHP5新参与的八个主要意义,因为在PHP
5从前的php4/php3都是一批的数据库扩充来跟各种数据库的连天和处理,如
php_mysql.dll。
PHP5.6中也将私下认可使用PDO的秘技连接,mysql扩张将被看作帮忙。官方:

PDO 目的在于令使用可移植 SQL
的台本运转杰出、可移植。本文中谈起的具有查询在选择任何 PDO
驱动程序时其运营质量应该一致 - 满含具有绑定输入变量和绑定输出列。

1、PDO配置

但有三个改造难点 - 当你使用 PDO_FETCH_ASSOC
抓取多少时,差异的驱动程序会以差别的点子赶回列名 -
某个会将列名转变为大写,某个调换为小写,某个则会使其呈查询中钦赐的样式。这对于
PHP 脚本来讲是三个暧昧的难题,因为数组键区分朗朗上口写。PDO
提供了多少个宽容性属性来帮助标准脚本的结果。上边包车型客车小代码段是上边PDO_FETCH_BOUND 示例的可移植版本,因为 setAttribute(State of Qatar 方法调用会指引PDO 将抓取再次回到的列名全部调换为大写:

利用PDO扩充早先,先要启用这么些增加,PHP.ini中,去掉”extension=php_pdo.dll”前边的”;”号,若要连接数据库,还亟需去掉与PDO相关的数据库扩张前面包车型客车”;”号(平时用的是php_pdo_mysql.dll),然后重启Nginx服务器就能够。

$dbh = new PDO(‘OCI:’, ‘scott’,
‘tiger’);$dbh-setAttribute(PDO_ATTR_CASE, PDO_CASE_UPPER);stmt =
$dbh-prepare(“SELECT extension, name from CREDITS”);if ($stmt-execute())
{$stmt-bindColumn(‘EXTENSION’, $extension);$stmt-bindColumn(‘NAME’,
$name);while ($stmt-fetch(PDO_FETCH_BOUND)) {echo
“Extension:$extension, Author:$name/n”; }}

    extension=php_pdo.dll
    extension=php_pdo_mysql.dll

除了 PDO_CASE_UPPER 之外,还有 PDO_CASE_LOWER和 PDO_CASE_NATURAL。

2、PDO连接mysql数据库

谬误和错误处理

    $dbh = new
PDO(“mysql:host=localhost;dbname=db_demo”,”root”,”password”);

可移植脚本的另一个难点是管理从各个数据库管理程序再次来到的各样分化的乖谬消息;某个数据库对于程序化处理错误的支撑工夫相当差,而其余部分数据库则具备特别充裕的错误代码。只要可行,PDO
将为你的脚本提供一个会集的错误代码,进而使您不要为应对可移植性的那么些上边所累。当然,PDO
还有大概会为驱动程序提供原生错误代码和谬误消息,以免您供给用它来进展确诊,大概错误代码映射不完全。

暗中同意不是长连接,若要使用数据库长连接,须要在终极加如下参数:

另一个麻烦 PHP
数据库扩张的一致性难点是错误处理攻略的一致性:有些扩充会回来的错误代码须要你手动抓取错误字符串,而别的一些扩张则只是产生PHP 警示。PDO 允许你从下列二种不一致的错误管理攻略中选用一种:

    $dbh = new
PDO(“mysql:host=localhost;dbname=db_demo”,”root”,”password”,”array(PDO::ATTR_PERSISTENT
=> true)”);  
    $dbh = null; //(释放)  

・PDO_ERRMODE_SILENT那是默许方式;它只是使用语句和数据库句柄对象的
errorCode(卡塔尔国 和 errorInfo(卡塔尔(قطر‎ 方法为你设置要检查的错误代码。

3、PDO设置属性

if (!$dbh-exec($sql)) {echo $dbh-errorCode() .”BR”;$info =
$dbh-errorInfo();// $info[0] == $dbh-errorCode(卡塔尔(قطر‎ 统一的失实代码//
$info[1] 是驱动程序特定的荒明清码// $info[2]
是驱动程序特定的乖谬字符串}

1State of Qatar、PDO有三种错误管理方式:

・PDO_ERRMODE_WA陆风X8NING除了设置错误代码之外,PDO 还有可能会时有发生 PHP
警示,您能够选择正规的 PHP
错误管理程序捕获该警报,并集中使用您思索好用于应用程序的任何错误管理/记录攻略,可能只是使该错误展现在浏览器中。
・PDO_ERRMODE_EXCEPTION除了设置错误代码之外,PDO 还有大概会抛出八个PDOException,并将其属性设置为带有该错误代码和音讯。然后,您能够在代码的较高档别捕获该极其,使用全局十一分管理程序捕获该特别,也许不对其开展拍卖而止住脚本。

    PDO::ERRMODE_SILENT不出示错误音信,只设置错误码
    PDO::ERRMODE_WA瑞鹰NING突显警报错
    PDO::ERRMODE_EXCEPTION抛出非常

try {$dbh-exec($sqlState of Qatar;} catch (PDOException $e卡塔尔 {// 呈现警示消息print
$e-getMessage(State of Qatar;$info = $e-errorInfo;// $info[0] == $e-code; unified
error code// $info[1] 是驱动程序特定的谬误代码// $info[2]
是驱动程序特定的大错特错字符串}

可通过以下语句来安装错误管理形式为抛出至极

请在乎,与警报或极度比较,静默形式针对运维时不当使用的能源起码,可是为了获得该速度,您捐躯了部分简单性,而变得有点繁杂。

    $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

归总错误代码表当前富含下列常量:
PDO_ERR_NONE、PDO_ERR_CANT_MAP、PDO_ERR_SYNTAX、PDO_ERR_CONSTRAINT、PDO_ERR_NOT_FOUND、PDO_ERR_ALREADY_EXISTS、PDO_ERR_NOT_IMPLEMENTED、PDO_ERR_MISMATCH、PDO_ERR_TRUNCATED、PDO_ERR_DISCONNECTED。

当设置为PDO::ETucsonRMODE_SILENT时得以透过调用 errorCode(卡塔尔 或
errorInfo(卡塔尔(قطر‎来获得错误音信,当然别的情况下也能够。

这几个常量所代表的意趣字面就能够推知,可是 PDO_ERR_CANT_MAP
代码除却;那是一个 PDO
特定的代码,约等于说它不能够将驱动程序特定的代码映射到统一的错误代码,因而你应该查询
errorInfo(卡塔尔(قطر‎ 方法再次回到的驱动程序特定代码来收获越多音讯。

2卡塔尔、因为不一样数据库对回到的字段名称大小写处理分歧,所以PDO提供了PDO::ATTENCORE_CASE设置项(包括PDO::CASE_LOWER,PDO::CASE_NATURAL,PDO::CASE_UPPEXC60),来规定重回的字段名称的轻重写。

数据类型

3卡塔尔、通过设置PDO::ATT奇骏_ORACLE_NULLS类型(包括PDO::NULL_NATURAL,PDO::NULL_EmpTY_STRING,PDO::NULL_TO_ST冠道ING)来钦赐数据库重回的NULL值在PHP中对应的数值。

PDO
在某种程度上类别不可以见到,因而它中意将数据表示为字符串,实际不是将其转移为整数或双精度类型。当时你或者对此有些吸引,可是原因特别简单:字符串类型是最确切的品种,在
PHP
中有着最不可胜言的选取范围;太早地将数据转变为整数要么双精度类型也许会招致截断或舍入错误。通过将数据以字符串抽取,PDO
为您提供了一些脚本决定,您能够运用普通的 PHP
类型调换工具来决定什么进展调换甚至曾几何时实行转移。

4、PDO常用艺术及其使用

NULL

    PDO::query(卡塔尔(قطر‎ 首假设用以有记录结果重返的操作,非常是SELECT操作
    PDO::exec(卡塔尔国主即使照准未有结果会集重返的操作,如INSERT、UPDATE等操作
    PDO::prepare(卡塔尔(قطر‎首假若预管理操作,需求经过$rs->execute(卡塔尔国来施行预管理此中的SQL语句,这么些措施可以绑定参数,功效比较强硬(防止sql注入就靠那个)
    PDO::lastInsertId()重临上次安顿操作,主键列类型是自增的最后的自增ID
    PDOStatement::fetch(卡塔尔国 是用来取得一条记下
    PDOStatement::fetchAll(卡塔尔国 是获取具有记录集到二个凑合
    PDOStatement::fetchColumn(卡塔尔国是获得结果钦命第一条记下的某部字段,缺省是率先个字段
    PDOStatement::rowCount():首假诺用以PDO::query(State of Qatar和PDO::prepare(卡塔尔进行DELETE、INSERT、UPDATE操作影响的结果集,对PDO::exec(卡塔尔国方法和SELECT操作无效

倘使结果集中的某列包蕴二个 NULL 值,PDO 则会将其映射为 PHP null
值。Oracle 在将数据再次来到 PDO 时会将空字符串转变为 NULL,可是 PHP
支持的其他其余数据库都不会那样处理,进而招致了可移植性难题。PDO
提供了三个使得程序级属性
PDO_ATTR_ORACLE_NULLS,该属性会为其余数据驱动程序模拟此行为:

5、PDO操作MySQL数据库实例

$dbh = new PDO(‘OCI:’, ‘scott’,
‘tiger’);$dbh-setAttribute(PDO_ATTR_ORACLE_NULLS, true卡塔尔;// 未来自此$dbh 打开的别样语句中的// 空字符串都将被改变为 NULL

<?php
$pdo = new PDO("mysql:host=localhost;dbname=db_demo", "root", "");
if ($pdo->exec("insert into db_demo(name,content) values('title','content')"))
{
    echo "插入成功!";
    echo $pdo->lastinsertid();
}
?>
<?php
$pdo = new PDO("mysql:host=localhost;dbname=db_demo", "root", "");
$rs = $pdo->query("select * from test");
$rs->setFetchMode(PDO::FETCH_ASSOC); // 关联数组形式
//$rs->setFetchMode(PDO::FETCH_NUM); // 数字索引数组形式
while ($row = $rs->fetch())
{
    print_r($row);
}
?>
<?php
foreach ($db->query("SELECT * FROM feeds") as $row)
{
    print_r($row);
}
?>

POD 的现状和未来

总计有稍微行数据

PDO
以往仍分外不成熟,可是会快速成熟起来。在编写制定本文之时,作者在本文中提到的别样内容都能够透过
PDO_OCI 驱动程序适用于 Oracle 8 或越来越高版本。

$sql="select count(*) from test";
$num = $dbh->query($sql)->fetchColumn();

早就布置增添以下重视特色,在不久将能够运用:

prepare方式

1.使用 PHP 流的 LOB 接济。
使用绑定参数,您能够将别的流动资金源作为输入或输出参数字传送递到在 LOB
上运转的查询中。与之类似,类型为 LOB 的出口参数将展现为 PHP
流,由此你能够利用 fread(State of Qatar、fwrite(State of Qatar、fseek(卡塔尔国和其余流函数来访问这一个参数。那时,在 PDO 中一向未曾 LOB 扶持。
2.漫长性连接和缓存的预管理语句。
漫长性连接让你可避防止在种种页面命中时打开和停业数据库服务器连接。缓存的预处理语句又升高了一步,它使您能够持久保持查询的预管理版本以至数据库句柄。
3.游标。 如今,PDO
只提供前向只读游标,不过以往会提供可滚动游标、REF-CU昂科威SOMurano、使用游标进行稳固更新,以至可更新滚动游标。

<?php
$stmt = $dbh->prepare("select * from test");
if ($stmt->execute())
{
    while ($row = $stmt->fetch())
    {
        print_r($row);
    }
}
?>

大家希望在 PHP 5.1 中私下认可启用 PHP 扩大,不过早先,大家盼望能让 PDO
在 PHP 5.0
发表时稳固运行,不过大家平日专门的工作中的压力稍微拖延了那个专门的学业。同一时候,通过
PECL 公布 PDO 使咱们能够在收到难题报告时做出答复,并依赖不一样于 PHP 5.0
发表时间表的时间表发布修复版本,由此你在 PHP 5.1 揭橥前即可使用 PDO。

prepare参数化查询

咱俩要求你的汇报

<?php
$stmt = $dbh->prepare("select * from test where name = ?");
if ($stmt->execute(array("david")))
{
    while ($row = $stmt->fetch(PDO::FETCH_ASSOC))
    {
        print_r($row);
    }
}
?>

假如您试用了
PDO,并且开掘了难点,请必得使用大家的大谬不然追踪软件将其告知给大家。假设你使用的是
Oracle 驱动程序,则请使用此页:

【上边包车型大巴话说根本了,怎么样幸免SQL注入】

_OCI

接纳PDO访问MySQL数据库时,真正的 real prepared statements
默许情状下是不利用的。为领悟除那么些主题素材,你必需禁止使用 prepared
statements的仿真效果。上面是采纳PDO创造链接的例证:

假让你使用的是其余驱动程序,则请用其名称替换该 UTiggoL 中 PDO_OCI。

<?php
$dbh = new PDO('mysql:dbname=dbtest;host=127.0.0.1;charset=utf8', 'user', 'pass');
$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
?>

若是您使用 PDO
时遇见标题,或然针对一些特征存在难点,恐怕有所特色恳求,请联系
pecl-dev@lists.php.net。倘令你愿意,当然还足以平昔关系自己(wez@php.net卡塔尔(قطر‎,可是请精心,我天天都会吸收接纳多量有关 PHP
的电子邮件;您只怕会意识只要首先与如今的邮件列表联系会越来越快获得答复。

setAttribute()这一行是强逼性的,它会报告 PDO
禁止使用模拟预管理语句,并接收 real parepared statements
。那能够保障SQL语句和对应的值在传递到MySQL服务器以前是不会被PHP拆解剖析的(禁绝了富有望的恶心SQL注入攻击)。固然您能够配备文件中设置字符集的习性(charset=utf8卡塔尔国,但是急需非常小心的是,老版本的
PHP( < 5.3.6)在DSN中是忽略字符参数的。

———–关于小编Wez Furlong 是 Brain Room Ltd.
的手艺组长,他在该商厦不但利用 PHP 用于 Web 开拓,还将其充任 Linux 和
Windows 应用程序和系统的嵌入式脚本引擎。Wez 是 PHP
的主干开荒职员,平日向 SQLite、COM/.Net、ActivePHP、mailparse 和 Streams
API 等投稿,他是 PECL 即 PHP 扩充社区库的“头儿”。他的提问公司的网页为 。

小编们来看一段完整的代码应用实例:

<?php
$dbh = new PDO("mysql:host=localhost; dbname=demo", "user", "pass");
$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); // 禁用prepared statements的仿真效果
$dbh->exec("set names 'utf8'");
$sql = "select * from test where name = ? and password = ?";
$stmt = $dbh->prepare($sql);
$exeres = $stmt->execute(array($testname, $pass));
if ($exeres)
{
    while ($row = $stmt->fetch(PDO::FETCH_ASSOC))
    {
        print_r($row);
    }
}
$dbh = null;
?>

地点这段代码就可以防守sql注入。为何吧?

当调用 prepare(卡塔尔(قطر‎ 时,查询语句已经发送给了数据库服务器,此时唯有占位符 ?
发送过去,未有顾客提交的数额;当调用到
execute(卡塔尔国时,顾客提交过来的值才会传送给数据库,他们是分别传送的,两个独立的,SQL攻击者没有一点时机。

然而大家须要小心的是以下二种处境,PDO并无法支持您一丝一毫防御SQL注入

1、你不能够让占位符 ? 取代一组值,如:

    SELECT * FROM blog WHERE userid IN ( ? );

2、你无法让占位符代替数据表名或列名,如:

    SELECT * FROM blog ORDER BY ?;

3、你不能够让占位符 ? 替代任何别的SQL语法,如:

    SELECT EXTRACT( ? FROM datetime_column) AS
variable_datetime_element FROM blog;

You can leave a response, or trackback from your own site.

Leave a Reply

网站地图xml地图