为了避免sql的非法注入,我们在新增、修改记录时使用pdo的预处理,然后进行绑定参数。
在上节课封装的sql类中添加以下代码:
/**
* 新增数据
* @param $data ,数据格式:['no'=>101,'name'=>'zhangsan']
* @return int 返回影响的行数
*/
public function add($data)
{
$sql = sprintf("insert into `%s` %s", $this->table, $this->formatInsert($data));
$sth = Db::pdo()->prepare($sql);
$sth = $this->formatParam($sth, $data);
$sth->execute();
return $sth->rowCount();
}
// 将数组转换成插入格式的sql语句
private function formatInsert($data)
{
$fields = array();
$names = array();
foreach ($data as $key => $value) {
$fields[] = sprintf("`%s`", $key);
$names[] = sprintf(":%s", $key);
}
$field = implode(',', $fields);
$name = implode(',', $names);
return sprintf("(%s) values (%s)", $field, $name);
}
/**
* 占位符绑定具体的变量值
* @param PDOStatement $sth 要绑定的PDOStatement对象
* @param array $params 参数,有三种类型:
* 1)如果SQL语句用问号?占位符,那么$params应该为
* [$a, $b, $c]
* 2)如果SQL语句用冒号:占位符,那么$params应该为
* ['a' => $a, 'b' => $b, 'c' => $c]
* 或者
* [':a' => $a, ':b' => $b, ':c' => $c]
*
* @return PDOStatement
*/
private function formatParam(PDOStatement $sth, $params = array())
{
foreach ($params as $param => &$value) {
$param = is_int($param) ? $param + 1 : ':' . ltrim($param, ':');
$sth->bindParam($param, $value);
}
return $sth;
}
add()方法是最主要的方法,对外公开。其它两个方法都是辅助的方法,并且是私有的。
我们写一段测试代码
$table = new Sql('student');
$table->add(['no'=>'185','name'=>'李四','sex'=>'男','age'=>20]);
请同学们回答以下问题:
我们调用了add方法,传递了一个数组,那么在add方法中构建的sql 语句是什么呢?请同学们一定写出来。
formatInsert()方法和formatParam()方法:主要功能是什么,返回什么类型的数据
提示:不能单纯的阅读代码,一定要写出来并且运行,在一些合适的位置使用echo 语句 或 print_r指令输入一些变量的结果,有助于对代码的理解。