连接数据库
PHP 操作数据库的方式有多种如 mysql 、 mysqli 、 PDO ,目前主要使用的是 PDO 处理。
PDO 提供了一个数据访问抽象层,这意味着,不管使用哪种数据库,都可以用相同的函数(方法)来查询和获取数据。
下面是使用 PDO 连接数据库的操作,当连接失败时将抛出异常。
<?php$config = ['host' => 'localhost','user' => 'root','password' => '','db' => 'test','charset' => 'utf8'];try{$dsn = sprintf('mysql:host=%s;dbname=%s;charset=%s',$config['host'], $config['db'],$config['charset']);$pdo = new PDO($dsn, $config['user'],$config['password']);}catch(PDOException $e){}
错误处理
| 错误类别 | 说明 |
|---|---|
| PDO::ERRMODE_SILENT | 不显示错误 |
| PDO::ERRMODE_WARNING | 显示警告错误 |
| PDO::ERRORMODE_EXCEPTION | 抛出异常 |
可以在连接时设置错误类型
$pdo = new PDO($dsn, $config['user'],$config['password'],[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);
也可以使用 setAttribute 方法设置错误处理方式。
...$pdo = new PDO($dns, $config['user'], $config['password']);$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);...
执行语句
使用 exec 方法可以发送执行语言
$pdo->exec("INSERT INTO news (title) VALUES('0x208.cc')");echo "自增主键:".$pdo->lastInsertId();
执行删除操作
$num = $pdo->exec("DELETE FROM news WHERE id = 1");echo "受影响的条数".$num;
发送查询
设置返回列名
| 属性 | 说明 |
|---|---|
| PDO::CASE_LOWER | 强制列名小写 |
| PDO::CASE_NATURAL | 保留数据库驱动返回的列名 |
| PDO::CASE_UPPER | 强制列名大写 |
$pdo->setAttribute(PDO::ATTR_CASE,PDO::CASE_LOWER);
返回结果
| 返回类型 | 说明 |
|---|---|
| $result->fetchAll(PDO::FETCH_ASSOC) | 获得关联数组 |
| $result->fetchAll(PDO::FETCH_NUM) | 获得索引数组 |
| $result->fetchAll(PDO::FETCH_BOTH) | 同时获取关联于索引数组 |
| $result->fetchAll(PDO::FETCH_OBJ) | 获取对象类型数据 |
fetchAll
一次获取所有结果
...$query = $pdo->query("select * from news");$rows = $query->fetchAll();print_r($rows);...
fetch
每次获取结果中的一条数据。
...$pdo = new PDO($dns, $config['user'], $config['password']);$query = $pdo->query("select * from news");while ($field = $query->fetch(PDO::FETCH_ASSOC)) {echo sprintf("编号:%s\t标题:%s<br/>", $field['id'], $field['title']);}...
预准备(预处理)
预准备是将 SQL 的解析阶段与参数绑定分开执行,从而可以有效的防止 SQL 注入。
SQL注入
下面来看一个 SQL 注入的例子。
$query = $pdo->query("SELECT * FROM news WHERE id={$_GET['id']}");
如果GET参数如下将产生 SQL 注入
a.php?id=3 or id>0
使用预准备
因为预准备是将解析与参数分开处理,可以有效的防止 SQL 注入。
$sql = "SELECT * FROM news WHERE id=:id";$sth = $pdo->prepare($sql);$sth->execute([':id' => $_GET['id']]);$rows = $sth->fetchAll(PDO::FETCH_ASSOC);print_r($rows);
预准备添加记录
$sql = "INSERT INTO news (title) VALUES(?)";$sth = $pdo->prepare($sql);$sth->execute(['0x208.cc']);echo $pdo->lastInsertId();
使用占位符操作
$sth = $pdo->prepare("SELECT * FROM news WHERE id>?");$sth->execute([3]);print_r($sth->fetchAll());
SQL生成器
处理类
下面构建一个SQL语句生成器,用于快速操作数据库。
<?phpnamespace Database;use PDO;use Exception;class DB{protected $link = null;protected $options = ['table'=>'','field'=>'','limit'=>'','order'=>'','where'=>''];public function __construct($config){$this->connect($config);}public function connect($config){if(is_null($this->link)){$dsn = sprintf('mysql:host=%s;dbname=%s;charset=utf8', $config['host'], $config['db']);$this->link = new PDO($dsn, $config['user'], $config['password'], [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);}return $this->link;}public function query($sql,array $vars=[]){$sth = $this->link->prepare($sql);$sth->execute($vars);return $sth->fetchAll();}public function execute($sql,array $vars=[]){$sth = $this->link->prepare($sql);return $sth->execute($vars);}public function field(...$fields){$this->options['field'] = '`'.implode('`,`', $fields) . '`';return $this;}public function table(string $table){$this->options['table'] = $table;return $this;}public function get(){$sql = "SELECT {$this->options['field']} FROM {$this->options['table']} {$this->options['where']} {$this->options['order']} {$this->options['limit']}";return $this->link->query($sql)->fetchAll();}public function orderBy(string $order){$this->options['order'] = " ORDER BY ".$order;return $this;}public function limit(...$limit){$this->options['limit'] = " LIMIT ".implode(',', $limit);return $this;}public function where(string $where){$this->options['where'] = " WHERE " . $where;return $this;}public function insert(array $vars){$sql = "INSERT INTO {$this->options['table']} (".implode(',', array_keys($vars)).") VALUES (".implode(',', array_fill(0,count($vars), '?')).")";return $this->link->execute($sql,array_values($vars));}public function delete(){$sql = "DELETE FROM {$this->options['table']} {$this->options['where']}";return $this->execute($sql);}public function update(array $vars){if(empty($this->options['where'])){throw new Exception("不能缺少更新条件");}$sql = "UPDATE {$this->options['table']} SET ".implode('=?', array_keys($vars))."=? {$this->options['where']}";return $this->execute($sql, array_values($vars));}}
对象实例
use Database\DB;include 'DB.php';$config = ['host' => 'localhost','user' => 'root','password' => '','db' => 'test'];try {...$db = new DB($config);...}catch(Exception $e){die($e->getMessage());}
预准备查询
...$db->query("SELECT * FROM news WHERE id>=:id", ['id' => 1]);...
预准备执行
$db->execute("INSERT INTO news (title) VALUES(?)", ['世界和平']);
查询操作
...$rows = $db->table('news')->field('id', 'title')->limit(1, 3)->orderBy('id desc')->where("id>3")->get();...
新增操作
...$db->table('news')->insert(['title'=>'天亮了']);...
更新操作
...$db->table('news')->where('id=2')->update(['title'=>'更新标题']);...
删除操作
...$db->table('news')->where('id=2')->delete();...
