创建|数据|数据库
function errorMessage($dbcode)
返回DB错误文本信息。
function &raiseError($code = DB_ERROR, $mode = false, $level = false,$debuginfo = false, $nativecode = false)
抛出一个错误。这个函数由DB来调用。
function setFetchMode($fetchmode)
设置缺省的fetch模式。
fetchmod有以下几种:
DB_FETCHMODE_DEFAULT :使用缺省的模式
DB_FETCHMODE_ORDERED :每条记录的数据列使用数字索引,从0开始
DB_FETCHMODE_ASSOC :每条记录的数据列使用字段名索引,同查询中的字段名一致
DB_FETCHMODE_FLIPPED:如果结果集是多维的,多条记录多个字段,一般来说返回一个2维数组,第一维是记录号,标明是第几条记录,第2维的数组则使用字段名或数字索引。DB_FETCHMODE_FLIPPED则会交换这个顺序,也就是说,第一层是字段名,第2维才是记录号.
function setOption($option, $value)
设置后端数据库选项。$options,$value分别是选项名和相应的值。
一般不用直接调用,在DB_Common及其子类的构建函数中会调用这个函数。
function getOption($option)
取得某个option的值
function prepare($query)
为execute()准备编译一个查询。对于某些后端数据库,这是通过仿真来实现的。返回编译后的查询句柄,出错则返回一个DB_Error对象。
function execute($stmt, $data = false)
执行编译后的查询。$stmt是由prepare返回的句柄。$data是参数数据,如果你使用的是参数查询,$data将要包含每个?参数的值
例子:
/**
* 下面是执行一个删除查询,从文章表中将指定用户的文章记录删除
*/
$sql = "delete from artilce where article.userid =$userid";
$qh = $db->prepare($sql);
if(DB::isError($qh)){
return $qh;
}
$result = $db->execute($qh);
return $result;
?>
function executeEmulateQuery($stmt, $data = false)
返回一个实际的查询字符串,供仿真prepare,execute的时候使用,内部函数。如果出错,则返回DB_Error对象
function executeMultiple( $stmt, &$data )
在同一个查询句柄上执行多个查询。$data必需是一个从0开始的数组,这个函数将 依次使用数组中的每一行数据来调用execute。这个函数一般用于参数查询。你可执行一次 查询的编译,然后将不同的参数值放入$data数组,然后就可一次同时执行查询了。需要注意,如果中间某个查询出错,剩余的查询不会继续进行而是返回错误。
function modifyQuery($query)
内部函数,用于后端数据库修正查询,后端数据库实现这个函数,然后返回进行优化和修正后查询串。例子:这是DB_mysql的实现,
function modifyQuery($query)
{
if ($this->options['optimize'] == 'portability') {
// "DELETE FROM table" gives 0 affected rows in MySQL.
// This little hack lets you know how many rows were deleted.
if (preg_match('/^\s*DELETE\s+FROM\s+(\S+)\s*$/i', $query)) {
$query = preg_replace('/^\s*DELETE\s+FROM\s+(\S+)\s*$/',
'DELETE FROM \1 WHERE 1=1', $query);
}
}
return $query;
}
?>
function &query($query)
执行一个查询,查询成功,如果是有结果集的查询,则回一个DB_Result对象,如果没有结果集的查询则返回DB_OK。
出错则返回DB_Error对象。
function &getOne($query, $params = array())
执行查询,并返回结果集中第一行第一列的数据。$params是参数值,如果后端数据库支持,将调用prepare/execute来使用这些参数。
例子:
$sql = "select id,date from article where userid= $userid orderby date";
$last = $db->getOne($sql);
if(DB::isError($last)){
echo "出错:".DB::errorMessage($last);
}
echo "id:".$last;
?>
function &getRow($query, $fetchmode = DB_FETCHMODE_DEFAULT, $params = array())
执行查询,请返回结果集的第一条记录。
$fetchmod 指定fetch模式,如果省略,使用缺省模式。
例子:
$sql = "select * from articles order by date desc";
$row = $db->getRow($sql);
if(DB::isError($row)){
echo "出错:".DB::errorMessage($row);
}
for($i=0;$i
}
?>
function &getCol($query, $col = 0, $params = array())
执行查询,并返回包含结果集中指定字段列的值的数组。
$col是要返回的列的索引,可以是整数,或者是关键字段名。
例子:
$sql = "select id,userid,date from articles order by date desc limit 100";
//只返回用户列表
$row = $db->getCol($sql,1);
if(DB::isError($row)){
echo "出错:".DB::errorMessage($row);
}
for($i=0;$i
}
?>
function &getAssoc($query, $force_array = false, $params = array())
执行查询,并返回一个关联数组。
$force_arry 强制返回数组。如果true,那么即使你的结果集里只有2个字段,那么关键字段对应的值也是一个只有一个元素的
数组。如果false,那么关键字段对应的值是一个标量了。
注意,这个关联数组有些特别:
如果你查询的是"select userid,name,reg_date from user",记录集是:
userid name reg_date
test testor 2001-07-05
test2 teest2 2001-07-06
那么返回的数组是这样的:
array( 'test' => array('testor','2001-0705'),
'test2'=> array('teest2','2001-07-06'
)
例子:
$sql = "select userid,name,reg_date,last_login from users limit 100";
$userinfo = $db->getAssoc($sql);
if(DB::isError($userinfo)){
die "错误!".DB::errorMessage($userinfo);
}
if(empty($userinfo)){
echo "warning:NO users!";
return;
}
/*现在,userinfo里面保存有用户的信息*/
function getUserInfo($user_id=''){
$info = $userinfo[$user_id];
if (empty($info){
echo "没有这个用户信息!";
}
return $info;
}
?>
function &getAll($query, $fetchmode = DB_FETCHMODE_DEFAULT, $params = array())
返回包含结果集中全部记录的数组。注意,如果你的结果集很大,不要使用这个函数。
例子:
$sql ="select * from users limit 1000";
$list = $db->getAll($sql);
if(DB::isError($list)){
die "数据库错误:".DB::errorMessage($list);
}
for ($i=0;$i
echo "
for($j=0;$j
}
echo "
}
?>
function autoCommit($onoff=false)
指定是否自动提交事务。有的后端数据库不支持。
function commit()
提交当前事务
function rollback()
回滚当前事务
function numRows($result)
返回结果集中的记录数
function affectedRows()
返回上一次查询操作的记录数
function nextId($seq_name, $ondemand = true)
返回指定的sequence的下一个值
function createSequence($seq_name)
创建一个Sequence
function dropSequence($seq_name)
删除一个Sequence
五、 更进一步,创建你自己的中间数据库应用层
到此,我们对于DB类的功能已经有了更深的了解。我们可以基于DB类来创建你自己的数据库应用层了。也许你会问,我为什么还要创建新的类,直接在我的应用程序中使用DB不好么?答案是,当然可以,但是我不推荐。
首先,虽然DB的功能很强大,但是仍然是过于底层的,你的类应该是面向应用的。你的这个数据库层应该屏蔽不需要使用的功能和函数,同时,也要提供一些更'高级'的方法,比如,你的应用程序不应该去联接数据库,释放资源,这些应该是透明的。那么这些工作就要由你的这个类来完成了。
其次,DB仍有一些缺陷,一旦找到比它更好的,你可以迅速地升级。你所要改的只是这个类的方法如何实现,你的应用程序的其他模块不会为此受到影响。
在你设计自己的类的时候,希望能够一些准则:
提供基本的自由的查询接口。包括query,execute.分别对应有结果集和无结果集的查询。
不要使用特定数据库的某些特性,即使因为放弃使用这些特征会给你增加不少的代码量。
尽量屏蔽一些数据库的操作细节,比如连接数据库,释放资源等等。
六、 DB的不足
上面我们讨论了DB的优点和一些使用的方法与技巧。但是,任何事物都不是十全十美的,DB类更是如此,由于DB乃至PEAR的开发时间并不长,因此DB并没有最终全部完成,其中也或多或少地存在一些BUG或者设计上的问题,需要我们在使用中去发现和修正。
MYSQL的问题
问题1:前段我在开发一个项目中,发现DB的MYSQL类有一个问题,那就是当你connect的时候,MYSQL类自动将当前数据库设置为$DSN中的数据库名。以后使用query的时候,都是使用当前数据库。下面是原来connect的代码:
if ($dsninfo["database"]) {
if (!mysql_select_db($dsninfo["database"], $conn)) {
return $this->raiseError(); // XXX ERRORMSG
}
}
这导致了一个后来令我费解的问题:
我的项目需要我连接2个数据,假设分别是user和test。test是我的主要数据库,但是我要从第一个数据库中user中取得用户信息,同时test中保存用户的权限信息。我为此做了一个中间的类CV_DB,用来实现我的数据库层。在CV_DB的创建函数中,我连接到指定的数据库,从而我可以这样使用:
$db1 = new CV("user");
$db2 = new CV("test");
后面当我执行,查询某个用户的信息的时候,出现了"该表不存在"的DB错误。但实际上这个表是存在的。最后,我发现原来是DB/mysql.php的问题,因为它的查询使用的是,mysql_query,而不是mysql_db_query,当我连接到第2个数据库的时候,MYSQL的当前数据库变成了第2个,这时我再执行针对第一个数据库的查询,当然会出错。
解决方式有2个,在创建CV的时候不连接到数据库,查询的时候连接,查询完毕后断开。或者,修改DB/Mysql.php。我选择后者,我将上面几行注释,然后将SimpleQuery中的mysql_query 替换成mysql_db_query.
问题2:mysql没有execute,因此它继承使用了DB_common中模拟方式,但是不幸地是,这带来了新的问题,在一些更新查询中,所要更新的数据有? &这2个特殊字符的时候,会出现问题,因为prepare认为这是参数查询的字符,将进行分析,导致无法更新数据。
解决方式也有2个:替换?和&,但是这样要考虑的事情很多。或者:直接使用simpleQuery或者query。
我选择后者,由于我的其他类只和CV――我这个中间数据库应用类打交道,于是,我在CV的execute方法中做了判断,如果是后端数据库是mysql,那么我直接调用simpleQuery,否则,调用后端数据库的prepare和execute。这样,实际的后端数据库对于我项目中的其他应用类是透明的,我可以简单地做相应的调整,这也是我设计数据库应用层的初衷。
DB的开发状态
DB目前仍在不断地开发当中,在DB/下面有一个文件STATUS,它描述了DB类的功能和各个后端数据库的实现情况,下面是PHP4.0.6这个发布中的开发情况:
"x" - 已经实现,但尚未测试implemented, but without tests
"t" - 已经实现,但是一个或多个测试没有通过implemented, but one or more tests fail
"T" - 实现并通过全部测试implemented, passing all tests
"e" - 仿真实现,没有测试emulated, without tests
"E" - 仿真实现,通过全部测试emulated, passing all tests
"n" - 返回 "not capable",没有这个能力提供该项功能
"-" - 没有实现
fbsql ifx mssql oci8 pgsql
FEATURE | ibase | msql | mysql | odbc | sybase
simpleQuery x x x x x T T x T x
numCols x x x x x T T x T x
numRows x n n x x T E n T n
errorNative x n x n n T x x T n
prepare/execute e x e e e E T e E e
sequences e n n n n E T n T n
affectedRows x n x n n T T n T n
fetch modes x x x x x T T x T x
fetch absolute rows x n x x x x n x x x
transactions x x n n n n x x x n
auto-commit x x n n n n x x x n
error mapping x - e - - T T x E -
tableInfo x n n n n T n n n n
七、参考资源
ADODB另一个非常好操纵数据库的PHP程序,DB的绝好的替代者
关于作者
潘凡(Night Sailer):北京赛迪数据有限公司工程师。主要研究兴趣是Perl,PHP与XML的应用,PHP的MVC开发模式,PERL-GTK的使用。您可以通过 E-mail:nightsailer@hotmail.com 跟他联系。

“你的组织要求你更改PIN消息”将显示在登录屏幕上。当在使用基于组织的帐户设置的电脑上达到PIN过期限制时,就会发生这种情况,在该电脑上,他们可以控制个人设备。但是,如果您使用个人帐户设置了Windows,则理想情况下不应显示错误消息。虽然情况并非总是如此。大多数遇到错误的用户使用个人帐户报告。为什么我的组织要求我在Windows11上更改我的PIN?可能是您的帐户与组织相关联,您的主要方法应该是验证这一点。联系域管理员会有所帮助!此外,配置错误的本地策略设置或不正确的注册表项也可能导致错误。即

Windows11将清新优雅的设计带到了最前沿;现代界面允许您个性化和更改最精细的细节,例如窗口边框。在本指南中,我们将讨论分步说明,以帮助您在Windows操作系统中创建反映您的风格的环境。如何更改窗口边框设置?按+打开“设置”应用。WindowsI转到个性化,然后单击颜色设置。颜色更改窗口边框设置窗口11“宽度=”643“高度=”500“>找到在标题栏和窗口边框上显示强调色选项,然后切换它旁边的开关。若要在“开始”菜单和任务栏上显示主题色,请打开“在开始”菜单和任务栏上显示主题

默认情况下,Windows11上的标题栏颜色取决于您选择的深色/浅色主题。但是,您可以将其更改为所需的任何颜色。在本指南中,我们将讨论三种方法的分步说明,以更改它并个性化您的桌面体验,使其具有视觉吸引力。是否可以更改活动和非活动窗口的标题栏颜色?是的,您可以使用“设置”应用更改活动窗口的标题栏颜色,也可以使用注册表编辑器更改非活动窗口的标题栏颜色。若要了解这些步骤,请转到下一部分。如何在Windows11中更改标题栏的颜色?1.使用“设置”应用按+打开设置窗口。WindowsI前往“个性化”,然

您是否在Windows安装程序页面上看到“出现问题”以及“OOBELANGUAGE”语句?Windows的安装有时会因此类错误而停止。OOBE表示开箱即用的体验。正如错误提示所表示的那样,这是与OOBE语言选择相关的问题。没有什么可担心的,你可以通过OOBE屏幕本身的漂亮注册表编辑来解决这个问题。快速修复–1.单击OOBE应用底部的“重试”按钮。这将继续进行该过程,而不会再打嗝。2.使用电源按钮强制关闭系统。系统重新启动后,OOBE应继续。3.断开系统与互联网的连接。在脱机模式下完成OOBE的所

任务栏缩略图可能很有趣,但它们也可能分散注意力或烦人。考虑到您将鼠标悬停在该区域的频率,您可能无意中关闭了重要窗口几次。另一个缺点是它使用更多的系统资源,因此,如果您一直在寻找一种提高资源效率的方法,我们将向您展示如何禁用它。不过,如果您的硬件规格可以处理它并且您喜欢预览版,则可以启用它。如何在Windows11中启用任务栏缩略图预览?1.使用“设置”应用点击键并单击设置。Windows单击系统,然后选择关于。点击高级系统设置。导航到“高级”选项卡,然后选择“性能”下的“设置”。在“视觉效果”选

在Windows11上的显示缩放方面,我们都有不同的偏好。有些人喜欢大图标,有些人喜欢小图标。但是,我们都同意拥有正确的缩放比例很重要。字体缩放不良或图像过度缩放可能是工作时真正的生产力杀手,因此您需要知道如何对其进行自定义以充分利用系统功能。自定义缩放的优点:对于难以阅读屏幕上的文本的人来说,这是一个有用的功能。它可以帮助您一次在屏幕上查看更多内容。您可以创建仅适用于某些监视器和应用程序的自定义扩展配置文件。可以帮助提高低端硬件的性能。它使您可以更好地控制屏幕上的内容。如何在Windows11

屏幕亮度是使用现代计算设备不可或缺的一部分,尤其是当您长时间注视屏幕时。它可以帮助您减轻眼睛疲劳,提高易读性,并轻松有效地查看内容。但是,根据您的设置,有时很难管理亮度,尤其是在具有新UI更改的Windows11上。如果您在调整亮度时遇到问题,以下是在Windows11上管理亮度的所有方法。如何在Windows11上更改亮度[10种方式解释]单显示器用户可以使用以下方法在Windows11上调整亮度。这包括使用单个显示器的台式机系统以及笔记本电脑。让我们开始吧。方法1:使用操作中心操作中心是访问

在iOS17中,Apple为其移动操作系统引入了几项新的隐私和安全功能,其中之一是能够要求对Safari中的隐私浏览选项卡进行二次身份验证。以下是它的工作原理以及如何将其关闭。在运行iOS17或iPadOS17的iPhone或iPad上,如果您在Safari浏览器中打开了任何“无痕浏览”标签页,然后退出会话或App,Apple的浏览器现在需要面容ID/触控ID认证或密码才能再次访问它们。换句话说,如果有人在解锁您的iPhone或iPad时拿到了它,他们仍然无法在不知道您的密码的情况下查看您的隐私


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

SublimeText3 Linux新版
SublimeText3 Linux最新版

MinGW - 适用于 Windows 的极简 GNU
这个项目正在迁移到osdn.net/projects/mingw的过程中,你可以继续在那里关注我们。MinGW:GNU编译器集合(GCC)的本地Windows移植版本,可自由分发的导入库和用于构建本地Windows应用程序的头文件;包括对MSVC运行时的扩展,以支持C99功能。MinGW的所有软件都可以在64位Windows平台上运行。

适用于 Eclipse 的 SAP NetWeaver 服务器适配器
将Eclipse与SAP NetWeaver应用服务器集成。

VSCode Windows 64位 下载
微软推出的免费、功能强大的一款IDE编辑器

记事本++7.3.1
好用且免费的代码编辑器