PHP PDO 操作 SQLite 数据库
SQLite 是一个单文件的离线 SQL 关系型数据库,它目前已经被集成到了很多编程语言中,可以直接使用。部分语言可能需要手动下载相关库使用。相比 MySQL 这一类数据库服务器来说,SQLite 不需要单独运行一个软件,数据都存储在一个 DB 文件中供程序访问,程序可以直接访问数据库文件,可以减少服务器内存的消耗。
PHP 中也集成了 SQLite 库,不需要单独下载相关库。
PDO 是 PHP 中一个用来操作数据库的接口,PDO 可以实现使用同样的方法来操作不同的数据库。如果您之前使用 PDO 操作过 MySQL 的话,换成 SQLite 也能很快上手。
启用 SQLite 扩展
很多 PHP 在安装的时候默认可能不会启用 SQLite 扩展,需要先开启 SQLite 扩展。
打开 php.ini
文件,找到:
extension=pdo_sqlite
如果前面有 ;
就删除 ;
。
建议使用 VSCode 或 Notepad++ 来编辑配置文件,通过不同颜色可以很方便的区分注释。
连接数据库
SQLite 数据库的文件是以 .db
结尾的文件,下面使用 PDO 打开一个 DB 文件:
try {
$pdo = new PDO('sqlite:data.db'); // 连接数据库
}catch (PDOException $e) {
echo $e->getMessage(); // 如果有错误就输出错误信息
}
因为 SQLite 的数据都存在一个 DB 文件中,也没有服务器之类的,所以需要的参数也比较少。如果 PHP 检测到 SQLite 的 DB 文件不存在就会创建一个 DB 文件。
SQLite 的数据都存储在 DB 文件中,使用 SQLite 可以不需要下载任何软件,在没有 SQLite 管理工具的情况下直接创建一个 DB 文件用 PHP 也能操作,你可以用 PHP 建立数据表之类的。SQLite 官方也提供了一个命令行的管理工具,可以到 https://www.sqlite.org/download.html 下载,如果只是简单管理的话也基本够用。
PDO 操作 SQLite 和操作 MySQL 差不多,主要是连接需要的参数不一样。
插入、删除、更改数据
这里还是使用上面创建的 PDO 来插入数据:
// SQL语句
$sql = "
INSERT INTO user
(user_name, password)
VALUES
('Zhang San', '123456')
";
// 插入数据
$result = $pdo->exec($sql);
插入数据可以使用 exec
方法,传入 SQL 语句,返回受影响的行数,如果插入失败会返回 0
。
PDO 的插入、更改、删除 都可以用 exec
方法,执行后会返回受影响的行数。
如果要查看 SQL 的增、删、改、查 之类的语句可以访问 MySQL 最基本的 增、删、改、查 ,虽然用的数据库是 MySQL,但是在 SQLite 上也能用。
如果 SQL 中包含变量之类的可以这样拼接:
$userName = $pdo->quote('Jackson');
$password = $pdo->quote('123');
// SQL语句
$sql = "
INSERT INTO user
(user_name, password)
VALUES
({$userName}, {$password})
";
// 插入数据
$result = $pdo->exec($sql);
如果是字符串之类的在插入之前可以用 PDO 的 quote
方法转换一下,数值类型的可以不需要。
$userName = $pdo->quote('Jackson');
$age = 30;
// SQL语句
$sql = "
INSERT INTO user
(user_name, age)
VALUES
({$userName}, {$age})
";
// 插入数据
$result = $pdo->exec($sql);
下面删除数据:
$sql = "
DELETE FROM user
WHERE
user_name = 'Jackson'
";
$result = $pdo->exec($sql);
上面删除了 user_name
为 Jackson
的数据,如果删除成功会返回 1
,也就是受影响的行数。
下面更改数据:
$sql = "
UPDATE user
SET
user_name = 'Li Si'
WHERE
user_name = 'Zhang San'
";
$result = $pdo->exec($sql);
上面把 user_name
为 Zhang San
的 user_name
改成了 Li Si
,更改后会返回受影响的行数。
查询
下面查询出 user
表的所有数据:
// SQL语句
$sql = "
SELECT
user_name, password
FROM
user
";
$data = $pdo->query($sql); // 查询
$data = $data->fetchAll(); // 把查询出的数据转换为数组
下面是 user
表的数据:
id | user_name | password |
---|---|---|
1 | Li Si | 123456 |
3 | Wang Wu | 565656 |
user
表中共有 2 条数据,查询出的数据转换为数组后如下:
Array
(
[0] => Array
(
[id] => 1
[0] => 1
[user_name] => Li Si
[1] => Li Si
[password] => 123456
[2] => 123456
)
[1] => Array
(
[id] => 3
[0] => 3
[user_name] => Wang Wu
[1] => Wang Wu
[password] => 565656
[2] => 565656
)
)
如果查询的数据不会超过 1 条的话可以使用 fetch
方法转换,如下:
$data = $pdo->query($sql); // 查询
$data = $data->fetch(); // 把查询出的数据转换为数组
转换后的数据如下:
Array
(
[id] => 1
[0] => 1
[user_name] => Li Si
[1] => Li Si
[password] => 123456
[2] => 123456
)
如果不需要数字索引的话,在转换的时候可以使用 PDO 的 FETCH_ASSOC
属性,使用 FETCH_ASSOC
后就不会包含数字键,
$data = $pdo->query($sql); // 查询
$data = $data->fetch(PDO::FETCH_ASSOC); // 把查询出的数据转换为数组
转换后的数据如下:
Array
(
[id] => 1
[user_name] => Li Si
[password] => 123456
)
fetchAll
方法也可以使用 FETCH_ASSOC
属性,如下:
$data = $pdo->query($sql); // 查询
$data = $data->fetchAll(PDO::FETCH_ASSOC); // 把查询出的数据转换为数组
转换后的数据如下:
Array
(
[0] => Array
(
[id] => 1
[user_name] => Li Si
[password] => 123456
)
[1] => Array
(
[id] => 3
[user_name] => Wang Wu
[password] => 565656
)
)
如果没有查询出数据,使用 fetchAll
或 fetch
转换后会返回一个空数组。
MySQL 在转换之前可以使用 rowCount()
方法来获取查询出的条数,但 SQLite 使用 rowCount()
是无法获取条数的,只会返回 0
。
参数化查询
上面编写 SQL 都是直接在 SQL String 中拼接数据,这种方式虽然写起来方便,但是也会增加 SQL 注入的风险。
参数化查询就是把 SQL 中需要传入的数据改为占位符,查询的时候再单独传入数据来替换占位符。使用参数化查询的时候,也不需要使用 PDO
的 quote
来转译字符,可以直接传入数据。
下面使用参数化查询来查询 user
表中 user_name
为 张三
的数据:
// SQL语句
$sql = 'SELECT * FROM user WHERE user_name = :user_name';
$query = $pdo->prepare($sql);
// 用来代替 :user_name 的数据
$queryData = array(':user_name' => '张三');
// 传入数据
$query->execute($queryData);
// 把查询到的数据转为数组
$data = $query->fetchAll(PDO::FETCH_ASSOC);
print_r($data);
SQL 的占位符使用 :占位符
,通过 PDO prepare
传入 SQL 后再使用 execute
传入占位符,替换占位符的数据是一个数组,数组的 key
就是占位符。
相关文章:
版权声明:本文为原创文章,版权归 Mr. Ma's Blog 所有,转载请联系博主获得授权。
本文地址:https://www.misterma.com/archives/888/
如果对本文有什么问题或疑问都可以在评论区留言,我看到后会尽量解答。