PHP 为老手开发人员提供了创建一些强大的 Web 解决方案的工具。而且,它还可以通过扩展添加额外的功能,从而使得创建解决方案更加容易。
附上DB类的源代码
DB实现类源码
1 class DB
2 {
3 /*获取表名*/
4 function table($table) {
5 return DB::_execute('table_name', $table);
6 }
7 /*删除*/
8 function delete($table, $condition, $limit = 0, $unbuffered = true) {
9 if(empty($condition)) {
10 $where = '1';//表达式为空,则where 1 网上有这方面的说明,不过我还没看懂什么意思,1=1为永真,1<>1为永假
11 } elseif(is_array($condition)) {
12 $where = DB::implode_field_value($condition, ' AND ');//若为数组,进行分隔,
13 } else {
14 $where = $condition;
15 }
16 $sql = "DELETE FROM ".DB::table($table)." WHERE $where ".($limit ? "LIMIT $limit" : '');//生成sql语句
17 return DB::query($sql, ($unbuffered ? 'UNBUFFERED' : ''));//执行
18 }
19 /*插入*/
20 function insert($table, $data, $return_insert_id = false, $replace = false, $silent = false) {
21
22 $sql = DB::implode_field_value($data);//分隔数组
23
24 $cmd = $replace ? 'REPLACE INTO' : 'INSERT INTO';//选择是replace into 或 insert into
25
26 $table = DB::table($table); //获取表
27 $silent = $silent ? 'SILENT' : '';//这个是指查询类型,一般分两种mysql_query和mysql_unbuffered_query,默认为mysql_query
28
29 $return = DB::query("$cmd $table SET $sql", $silent);//生成sql语句
30
31 return $return_insert_id ? DB::insert_id() : $return;//返回新插入的行的id
32
33 }
34 /*更新*/
35 function update($table, $data, $condition, $unbuffered = false, $low_priority = false) {
36 $sql = DB::implode_field_value($data);//分隔数组
37 //low_priority意为低优先级,在网上大致查了下,意思是它的优先级不会高于读操作
38 //假如在写的时候,有一个读的操作,那么系统允许,把读操作插入到写前面,等读完了,再写
39 $cmd = "UPDATE ".($low_priority ? 'LOW_PRIORITY' : '');
40 $table = DB::table($table);//获取表名
41 $where = '';
42 if(empty($condition)) {//判断表达式
43 $where = '1';
44 } elseif(is_array($condition)) {
45 $where = DB::implode_field_value($condition, ' AND ');
46 } else {
47 $where = $condition;
48 }
49 $res = DB::query("$cmd $table SET $sql WHERE $where", $unbuffered ? 'UNBUFFERED' : '');//生成sql语句
50 return $res;//返回执行结果
51 }
52 /*分隔数组*/
53 function implode_field_value($array, $glue = ',') {
54 $sql = $comma = '';
55 foreach ($array as $k => $v) {
56 $sql .= $comma."`$k`='$v'";
57 $comma = $glue;
58 }
59 return $sql;
60 }
61 /*获取插入新行的id*/
62 function insert_id() {
63 return DB::_execute('insert_id');
64 }
65 /*生成关联数组*/
66 function fetch($resourceid, $type = MYSQL_ASSOC) {
67 return DB::_execute('fetch_array', $resourceid, $type);
68 }
69 /*获取结果集中的第一行数据*/
70 function fetch_first($sql) {
71 DB::checkquery($sql);
72 return DB::_execute('fetch_first', $sql);
73 }
74 /*返回结果集中的某一行*/
75 function result($resourceid, $row = 0) {
76 return DB::_execute('result', $resourceid, $row);
77 }
78 /*返回结果集中的第一行*/
79 function result_first($sql) {
80 DB::checkquery($sql);
81 return DB::_execute('result_first', $sql);
82 }
83 /*执行查询*/
84 function query($sql, $type = '') {
85 DB::checkquery($sql);//过滤sql语句
86 return DB::_execute('query', $sql, $type);
87 }
88 /*select语句查询所影响的行数*/
89 function num_rows($resourceid) {
90 return DB::_execute('num_rows', $resourceid);
91 }
92 /*update,insert,delete语句所影响的行数*/
93 function affected_rows() {
94 return DB::_execute('affected_rows');
95 }
96 /*释放内存*/
97 function free_result($query) {
98 return DB::_execute('free_result', $query);
99 }
100 /*输出错误信息*/
101 function error() {
102 return DB::_execute('error');
103 }
104 /*获取错误编号*/
105 function errno() {
106 return DB::_execute('errno');
107 }
108 //DB::_execute('table_name', $table)
109 //相当于$res = $db->table_name($table);
110 function _execute($cmd , $arg1 = '', $arg2 = '') {
111 static $db;
112 if(empty($db)) $db = & DB::object();//创建db_mysql对象
113 $res = $db->$cmd($arg1, $arg2);
114 return $res;
115 }
116 /*实例化db_mysql对象*/
117 function &object() {
118 static $db;
119 if(empty($db)) $db = new db_mysql();
120 return $db;
121 }
122 /*检查sql语句*/
123 function checkquery($sql) {
124 static $status = null, $checkcmd = array('SELECT', 'UPDATE', 'INSERT', 'REPLACE', 'DELETE');
125 if($status === null) $status = getglobal('config/security/querysafe/status');
126 if($status) {
127 $cmd = trim(strtoupper(substr($sql, 0, strpos($sql, ' '))));
128 if(in_array($cmd, $checkcmd)) {
129 $test = DB::_do_query_safe($sql);
130 if($test < 1) DB::_execute('halt', 'security_error', $sql);
131 }
132 }
133 return true;
134 }
135 /*过滤sql语句*/
136 function _do_query_safe($sql) {
137 static $_CONFIG = null;
138 if($_CONFIG === null) {
139 $_CONFIG = getglobal('config/security/querysafe');
140 }
141
142 $sql = str_replace(array('\\\\', '\\\'', '\\"', '\'\''), '', $sql);
143 $mark = $clean = '';
144 if(strpos($sql, '/') === false && strpos($sql, '#') === false && strpos($sql, '-- ') === false) {
145 $clean = preg_replace("/'(.+?)'/s", '', $sql);
146 } else {
147 $len = strlen($sql);
148 $mark = $clean = '';
149 for ($i = 0; $i <$len; $i++) {
150 $str = $sql[$i];
151 switch ($str) {
152 case '\'':
153 if(!$mark) {
154 $mark = '\'';
155 $clean .= $str;
156 } elseif ($mark == '\'') {
157 $mark = '';
158 }
159 break;
160 case '/':
161 if(empty($mark) && $sql[$i+1] == '*') {
162 $mark = '/*';
163 $clean .= $mark;
164 $i++;
165 } elseif($mark == '/*' && $sql[$i -1] == '*') {
166 $mark = '';
167 $clean .= '*';
168 }
169 break;
170 case '#':
171 if(empty($mark)) {
172 $mark = $str;
173 $clean .= $str;
174 }
175 break;
176 case "\n":
177 if($mark == '#' || $mark == '--') {
178 $mark = '';
179 }
180 break;
181 case '-':
182 if(empty($mark)&& substr($sql, $i, 3) == '-- ') {
183 $mark = '-- ';
184 $clean .= $mark;
185 }
186 break;
187
188 default:
189
190 break;
191 }
192 $clean .= $mark ? '' : $str;
193 }
194 }
195
196 $clean = preg_replace("/[^a-z0-9_\-\(\)#\*\/\"]+/is", "", strtolower($clean));
197
198 if($_CONFIG['afullnote']) {
199 $clean = str_replace('/**/','',$clean);
200 }
201
202 if(is_array($_CONFIG['dfunction'])) {
203 foreach($_CONFIG['dfunction'] as $fun) {
204 if(strpos($clean, $fun.'(') !== false) return '-1';
205 }
206 }
207
208 if(is_array($_CONFIG['daction'])) {
209 foreach($_CONFIG['daction'] as $action) {
210 if(strpos($clean,$action) !== false) return '-3';
211 }
212 }
213
214 if($_CONFIG['dlikehex'] && strpos($clean, 'like0x')) {
215 return '-2';
216 }
217
218 if(is_array($_CONFIG['dnote'])) {
219 foreach($_CONFIG['dnote'] as $note) {
220 if(strpos($clean,$note) !== false) return '-4';
221 }
222 }
223
224 return 1;
225
226 }
227
228 }
PHP Extension and Application Repository (PEAR) 是一个帮助开发人员通过 API 或包(package)创建解决方案的框架。PEAR 还是一个分布式系统,该系统提供了自动安装这些包的一个方法。在这篇文章中,我将着重强调我认为其中最重要的一个包:DB 包。
DB 包是一个面向对象风格的抽象层,是对 PHP 的底层数据库连接和查询的抽象;与 PHP 4 和 PHP 5 兼容。DB 包目前支持以下扩展:dbase、fbsql、interbase、informix、msql、mssql、mysql、mysqli、oci8、odbc、pgsql、sqlite和 Sybase。
如果用过mysql_* 函数添加和查询MySQL数据库,那么你可以熟悉它所提供的不同的结果集(resultsets)。最常用的两个结果集要么是一个数组,在这个数组中每个域(field)是一个被索引的元素,要么是一个组合数组,其中每个字段是一个键/值(key/value)对。PEAR DB 提供这两个结果集,以及一个对象类型,这个对象类型创建一个动态对象,其中每个域作为对象的一个属性。在 Windows 平台下使用 ADO 连接的开发人员可能会很熟悉组合数组和对象类型。
在 ADO 中,结果集(或者记录集(Recordset))是作为一个可导航的行集合返回的。每一行是 Field 对象的一个集合。每个 Field 对象都有一个 Name 和一个 Value 属性(也就是字段的名称和那个所包含的数据)。下面在 PHP 中访问字段数据的一个例子:
require_once("DB.php");
$dsn = "mysql://username:password@localhost/database";
$options = array(
'debug' => 2,
'portability' => DB_PORTABILITY_ALL,
);
$db =& DB::connect($dsn, $options);
$db->setFetchMode(DB_FETCHMODE_ASSOC);
$res =& $db->query("SOME SQL STRING");
$row =& $res->fetchRow();
echo $row['field1'];
下面是如何在 VBScript 中使用 ADO 来实现:
Dim conn, rs
Set conn = Server.CreateObject("ADODB.Connection")
Set rs = Server.CreateObject("ADODB.Recordset")
conn.ConnectionString = "some connection string"
Set rs.ActiveConnection = conn
rs.Open "SOME SQL STRING"
Response.Writers.Fields("field1").Value
你可以看到这两种方法具有相似之处。首先,要建立一个到数据库的连接。然后,发出一个查询并接收一个结果集。像 ADO 一样,PEAR DB 包提供对所有与数据库服务通信相关的低层结果的抽象。
如果你是 PEAR 新手,那么你可能需要了解如何在你自己的系统上实现包。作为一个抽象系统,PEAR 可以使你很容易地实现包。我对承载 Web 站点的机器没有太多的控制权,只能限于通过 FTP 和一个由主机供应商所提供的“控制面板”来管理我自己的虚拟主机。
在安装 PEAR 之前,先将这段脚本复制到主机系统上的一个 PHP 文件中。