封装pdo 使其更好用(具体实现请查看我的php-library项目) 初始化(以MySQL为例子):// 实例化对象方式1:// 引入微内核框架(或分别引入需要的文件)include '../library/initialize.php';$pdo
初始化(以MySQL为例子): // 实例化对象方式1: // 引入微内核框架(或分别引入需要的文件) include '../library/initialize.php'; $pdo = new PDOMySQLDriver(); $func = new Utility(); $store = new Session(); // 实例化对象方式2: // 引入微内核框架 include '../library/initialize.php'; // 使用单例模式加载,并加载错误、异常代码追踪器(Guard) $loader = Master::singleton(array('Guard')); $pdo = $loader['PDOMySQLDriver']; $func = $loader['Utility']; $store = $loader['Session']; 查询数据: // 查询ID为5的那行数据的年龄信息: $age = $pdo->mapField('t_person', array('id'=>5), 'age'); //也可以这样(主键作为唯一的条件,字段名可以忽略) $age = $pdo->mapField('t_person', 5, 'age'); // 还可以这样使用原生语句 $age = $pdo->fetchField('select `age` from `t_person` where `id`=5'); // 查询年龄为5的那行数据 $personInfo = $pdo->mapRow('t_person', array('age'=>5)); // 查询ID为5的那行数据(主键作为唯一条件,字段名可省略) $personInfo = $pdo->mapRow('t_person', 5); // 查询年龄为5的那行数据,只取id,name两个字段 $personInfo = $pdo->mapRow('t_person', array('age'=>5), array('id', 'name')); // 查询年龄为5且是男性的那行数据,只取id,name两个字段 $personInfo = $pdo->mapRow('t_person', array('age'=>5, sex=>'男'), array('id', 'name')); // 还可以这样使用原生语句 $personInfo = $pdo->fetchRow("select `id`, `age` from `t_person` where `age`>5 and `sex`='男'"); // 查询所有年龄为5的数据 $personData = $pdo->mapData('t_person', array('age'=>5)); // 查询所有年龄为5且是男性的数据,只取id,name两个字段 $personData = $pdo->mapData('t_person', array('age'=>5, sex=>'男'), array('id', 'name')); // 条件使用键值对的形式只能表达一种逻辑(即,相等),它在底层上是进行预查询的,是SQL安全的! // 但有时业务不仅仅是相等的逻辑,如查询年龄大于7的所有数据,为此引入条件模版,将拼合的数据部分用特殊标记括起来,底层使用:key的形式替换并进行预查询 // SQL注入通常是条件数据拼凑以及非法输入造成的,这其中逻辑运算是我们指定的,但数据是外来的,是不可信的,所以要将数据部分单独用特殊标记包裹起来 // 由此可以使用下面的方法进行自动包裹:(包裹的开始及结束标记见下文的描述,建议使用方法,因为还涉及到字符冲突及转义) // 请注意在双引号中使用PHP变量时,正确的写法如:"find_in_set(id,{$pdo->enc($id_set)})" ,道理你懂得! $personData = $pdo->mapData('t_person', array('age>{$pdo->enc(7)}'), array('id', 'name')); // 请注意如果我们已经确定age就是一个数字,就没有必要加标记了,直接写死即可,如: $personData = $pdo->mapData('t_person', array('age>7'), array('id', 'name')); // 请注意在map开头的这一类方法中,只有条件模版没有指定键值(数字除外),才会对其进行处理,这也是防止误处理的判断(因为此时键值已经没有意义了,有意义的键值必须是一个合法的数据库字段名) // 有时查询的不仅仅是字段,还可能伴有一些聚合函数及运算,为此引入了查询模版,将表达式整体用特殊标记括起来 // 查询时,返回字段一般是我们指定的,可以排除SQL注入的可能,故底层没有做特殊处理,所以整体用特殊标记括起来,告诉底层这是个表达式,而不是字段!(在查询返回字段时,键值总是没有意义的) // 如查询7岁以上的男性人数 $counter = $pdo->mapRow('t_person', array('age>7'),array('{$pdo->enc('count(`sex`)')}')); // 应用条件模版时,模糊查询中的%的位置应当如下(查询名字中有‘王’字的人) $personData = $pdo->mapData('t_person', array('name like {$pdo->enc('%王%')}'), array('id', 'name')); 更新数据 // 将ID为5的数据的年龄设置为7 $pdo->mapUpdate('t_person', array('id'=>5), array('age'=>7)); // 也可以这样(主键作为唯一的条件,名字可以忽略) $pdo->mapUpdate('t_person', 5, array('age'=>7)); // mapUpdate方法不允许空条件出现(安全考虑)! 插入数据 // 向t_person表插入一条数据(id自增) $pdo->postData('t_person', array( 'name'=>'张三', 'age'=>5, 'sex'=>'男', 'addr'=>'大王家村' )); // 同update 中的set子句一样insert语句不支持模版形式 删除数据 // 删除ID为5的数据 $pdo->mapDelete('t_person', array('id'=>5)); // 也可以这样(主键作为唯一的条件,名字可以忽略) $pdo->mapDelete('t_person', 5); // 同更新一样mapDelete方法都不允许空条件出现! 对exec方法扩展,简化‘非查询类’的预查询 // PDO中原生的exec方法只能执行一般的sql,预查询则很麻烦,如执行一个更新: $stmt = $pdo->prepare("update `t_person` set age=age+1 where age>?"); $count = $stmt->execute(array(5)); // 返回受影响的行数 // 现在你可以将其合并了: $count = $pdo->exec("update `t_person` set age=age+1 where age>?", array(5)); 对query方法扩展,添加条件模版支持,防止SQL注入 // 进行预查询通常很麻烦,进行查询条件拼凑时更麻烦(如多条件查询,每次的查询条件是跟用户的意愿有关) // 为此能将一般的查询自动转换为预查询是一个好主意,所以我在query中进行了扩展: // query($query, $tplCheck=null, $fetchMode=null) // 当$tplCheck设为true时,会检查SQL语句中是否有条件模版,并自动转换(没有设置时,取决与全局变量$queryTplCheck) // 使用条件模版自然有稍许的性能损失,如果是类似向数据库中导入信息的操作,还是关掉吧!($tplCheck优先级高于$queryTplCheck) // 例如查询姓名中含有‘王’字的人,使用条件模版可以这样处理: $stmt = $pdo->query("select * from `t_person` where name like {$pdo->enc('%'.$name.'%')}"); // 受 $queryTplCheck 此全局选项影响的方法有fetchField()、fetchRow()、fetchData(), // 换句话说,它们都支持SQL语句中含有条件模版的写法,因为只有它们底层都调用了query方法!! // 还有一点需要注意的时,当你开启了$queryTplCheck选项时,你应当将对可预见的字符串类、日期类等数据使用条件模版(默认开启), 对模版进行转义 (最后一点,但也是很重要的) 最开始的时候,我是用‘{^’ 和 ‘$}’将数据包裹起来,但当用户数据中含有 ‘{^’ 或 ‘$}’ 意想不到的事情就会出现,虽然这种情况出现的几率很少, 但我还是附加了一个转义方法: // 使用转义方法的原生查询语句(将用户数据中的 ‘{^’ 替换为 ‘\{\^’ ,‘$}’ 替换为 ‘\$\}’ ) $stmt = $pdo->query("select * from `t_person` where name like {$pdo->enc('%'.$name.'%')}"); $stmt = $pdo->query("select * from `t_person` where name = {$pdo->enc($name)}"); 为什么不使用自带的quote方法呢,这主要是考虑同map中的模板条件相一致。 总结: 通常参数的顺序是表名, 条件, ...; 查询时,注意方法名字是以fetch开头,还是map开头,注意返回的是field、row还是data; map开头的这一类方法的条件部分都可以用条件模版的形式哦!