原文: https://zetcode.com/php/sqlite3/

这是针对 SQLite 版本 3 数据库的 PHP 编程教程。 它涵盖了使用 PHP 语言进行 SQLite 编程的基础。

要使用本教程,我们必须在系统上安装 PHP CLI。

为了使用 SQLite 数据库,我们可以安装sqlite3命令行工具或 SQLite 浏览器 GUI。

  1. $ php -v
  2. PHP 7.2.11 (cli) (built: Oct 10 2018 02:39:52) ( ZTS MSVC15 (Visual C++ 2017) x86 )
  3. Copyright (c) 1997-2018 The PHP Group
  4. Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies

在本教程中,我们使用 PHP 7.2.11。

  1. ...
  2. ;extension=sockets
  3. extension=sqlite3
  4. ;extension=tidy
  5. ...

SQLite 随 PHP 一起提供; 我们不需要安装它。 我们必须在php.ini文件中启用 sqlite3 扩展。

SQLite

SQLite 是嵌入式关系数据库引擎。 该文档称其为自包含,无服务器,零配置和事务型 SQL 数据库引擎。 如今,它在全球使用着数亿册,非常受欢迎。 几种编程语言都内置了对 SQLite 的支持,包括 PHP 和 Python。

创建 SQLite 数据库

我们使用sqlite3命令行工具创建一个新数据库。

  1. $ sqlite3 test.db
  2. SQLite version 3.27.2 2019-02-25 16:06:06
  3. Enter ".help" for usage hints.
  4. sqlite>

我们为sqlite3工具提供了一个参数; test.db是数据库名称。 这是我们磁盘上的文件。 如果存在,则将其打开。 如果不是,则创建它。

  1. sqlite> .tables
  2. sqlite> .exit
  3. $ ls
  4. test.db

.tables命令提供test.db数据库中的表的列表。 当前没有表格。 .exit命令终止sqlite3命令行工具的交互式会话。 ls命令显示当前工作目录的内容。 我们可以看到test.db文件。 所有数据将存储在该单个文件中。

PHP SQLite3 版本示例

在以下示例中,我们获得了 SQLite 数据库的版本。

version.php

  1. <?php
  2. $ver = SQLite3::version();
  3. echo $ver['versionString'] . "\n";
  4. echo $ver['versionNumber'] . "\n";
  5. var_dump($ver);

SQLite3::version()返回 SQLite 数据库的版本。

  1. $ php version.php
  2. 3.20.1
  3. 3020001
  4. array(2) {
  5. ["versionString"]=>
  6. string(6) "3.20.1"
  7. ["versionNumber"]=>
  8. int(3020001)
  9. }

这是输出。

version2.php

  1. <?php
  2. $db = new SQLite3('test.db');
  3. $version = $db->querySingle('SELECT SQLITE_VERSION()');
  4. echo $version . "\n";

程序返回 SQLite 数据库的当前版本。 这次我们执行了SELECT SQLITE_VERSION()语句。

  1. $db = new SQLite3('test.db');

我们创建一个 SQLite3 对象并打开一个 SQLite3 数据库连接。

  1. $version = $db->querySingle('SELECT SQLITE_VERSION()');

querySingle()执行查询并返回单个结果。

  1. $ php version2.php
  2. 3.20.1

This is the output.

PHP SQLite3 执行

exec()对给定的数据库执行无结果查询。

create_table.php

  1. <?php
  2. $db = new SQLite3('test.db');
  3. $db->exec("CREATE TABLE cars(id INTEGER PRIMARY KEY, name TEXT, price INT)");
  4. $db->exec("INSERT INTO cars(name, price) VALUES('Audi', 52642)");
  5. $db->exec("INSERT INTO cars(name, price) VALUES('Mercedes', 57127)");
  6. $db->exec("INSERT INTO cars(name, price) VALUES('Skoda', 9000)");
  7. $db->exec("INSERT INTO cars(name, price) VALUES('Volvo', 29000)");
  8. $db->exec("INSERT INTO cars(name, price) VALUES('Bentley', 350000)");
  9. $db->exec("INSERT INTO cars(name, price) VALUES('Citroen', 21000)");
  10. $db->exec("INSERT INTO cars(name, price) VALUES('Hummer', 41400)");
  11. $db->exec("INSERT INTO cars(name, price) VALUES('Volkswagen', 21600)");

该程序将创建一个cars表,并将八行插入该表中。

  1. $db->exec("CREATE TABLE cars(id INTEGER PRIMARY KEY, name TEXT, price INT)");

该 SQL 语句创建一个新的cars表。 该表有三列。 请注意,在 SQLite 数据库中,INTEGER PRIMARY KEY列是自动增加的。

  1. $db->exec("INSERT INTO cars(name, price) VALUES('Audi', 52642)");
  2. $db->exec("INSERT INTO cars(name, price) VALUES('Mercedes', 57127)");

这两行将两辆车插入表。

  1. sqlite> .mode column
  2. sqlite> .headers on

我们使用sqlite3工具验证写入的数据。 首先,我们修改数据在控制台中的显示方式。 我们使用列模式并打开标题。

  1. sqlite> select * from cars;
  2. id name price
  3. ---------- ---------- ----------
  4. 1 Audi 52642
  5. 2 Mercedes 57127
  6. 3 Skoda 9000
  7. 4 Volvo 29000
  8. 5 Bentley 350000
  9. 6 Citroen 21000
  10. 7 Hummer 41400
  11. 8 Volkswagen 21600

这是我们已写入cars表的数据。

PHP SQLite3 lastInsertRowID

有时,我们需要确定最后插入的行的 ID。 在 PHP SQLite3 中,我们使用lastInsertRowID()方法。

last_rowid.php

  1. <?php
  2. $db = new SQLite3(':memory:');
  3. $db->exec("CREATE TABLE friends(id INTEGER PRIMARY KEY, name TEXT)");
  4. $db->exec("INSERT INTO friends(name) VALUES ('Tom')");
  5. $db->exec("INSERT INTO friends(name) VALUES ('Rebecca')");
  6. $db->exec("INSERT INTO friends(name) VALUES ('Jim')");
  7. $db->exec("INSERT INTO friends(name) VALUES ('Robert')");
  8. $last_row_id = $db->lastInsertRowID();
  9. echo "The last inserted row Id is $last_row_id";

我们在内存中创建一个friends表。 ID 会自动递增。

  1. $db->exec("CREATE TABLE friends(id INTEGER PRIMARY KEY, name TEXT)");

在 SQLite3 中,INTEGER PRIMARY KEY列自动增加。 还有一个AUTOINCREMENT关键字。 在INTEGER PRIMARY KEY AUTOINCREMENT中使用时,会使用稍微不同的 ID 创建算法。

  1. $db->exec("CREATE TABLE friends(id INTEGER PRIMARY KEY, name TEXT)");
  2. $db->exec("INSERT INTO friends(name) VALUES ('Tom')");
  3. $db->exec("INSERT INTO friends(name) VALUES ('Rebecca')");
  4. $db->exec("INSERT INTO friends(name) VALUES ('Jim')");
  5. $db->exec("INSERT INTO friends(name) VALUES ('Robert')");

使用自动增量时,我们必须明确声明列名,而忽略自动增量的列名。 这四个语句在friends表中插入四行。

  1. $last_row_id = $db->lastInsertRowID();

使用lastInsertRowID()获得最后插入的行 ID。

  1. $ php last_rowid.php
  2. The last inserted row Id is 4

我们看到了程序的输出。

PHP SQLite3 查询

query()方法执行 SQL 查询并返回结果对象。

fetch_all.php

  1. <?php
  2. $db = new SQLite3('test.db');
  3. $res = $db->query('SELECT * FROM cars');
  4. while ($row = $res->fetchArray()) {
  5. echo "{$row['id']} {$row['name']} {$row['price']} \n";
  6. }

该示例从cars表中检索所有数据。

  1. $res = $db->query('SELECT * FROM cars');

该 SQL 语句从cars表中选择所有数据。

  1. while ($row = $res->fetchArray()) {

fetchall()检索结果行作为关联数组或数字索引数组,或两者都检索(默认为两者)。 如果没有更多行,则返回false

  1. $ php fetch_all.php
  2. 1 Audi 52642
  3. 2 Mercedes 57127
  4. 3 Skoda 9000
  5. 4 Volvo 29000
  6. 5 Bentley 350000
  7. 6 Citroen 21000
  8. 7 Hummer 41400
  9. 8 Volkswagen 21600

这是示例的输出。

PHP SQLite3 escapeString

escapeString()返回已正确转义的字符串。

escape_string.php

  1. <?php
  2. $db = new SQLite3('test.db');
  3. $sql = "SELECT name FROM cars WHERE name = 'Audi'";
  4. $escaped = SQLite3::escapeString($sql);
  5. var_dump($sql);
  6. var_dump($escaped);

该示例对查询中的字符串进行转义。

  1. $ php escape_string.php
  2. string(41) "SELECT name FROM cars WHERE name = 'Audi'"
  3. string(43) "SELECT name FROM cars WHERE name = ''Audi''"

This is the output of the example.

PHP SQLite3 参数化语句

SQL 语句通常是动态构建的。 用户提供一些输入,并且此输入已内置到语句中。 每当我们处理来自用户的输入时,我们都必须谨慎。 它具有一些严重的安全隐患。 动态构建 SQL 语句的推荐方法是使用参数绑定。

使用prepare()创建参数化查询; 它准备要执行的 SQL 语句并返回一个语句对象。

PHP SQLite3 具有bindParam()bindValue()方法来将值绑定到占位符。 它允许将数据绑定到问号或命名的占位符。

带问号的参数化语句

在第一个示例中,我们使用问号的语法。

prepared.php

  1. <?php
  2. $db = new SQLite3('test.db');
  3. $stm = $db->prepare('SELECT * FROM cars WHERE id = ?');
  4. $stm->bindValue(1, 3, SQLITE3_INTEGER);
  5. $res = $stm->execute();
  6. $row = $res->fetchArray(SQLITE3_NUM);
  7. echo "{$row[0]} {$row[1]} {$row[2]}";

我们选择使用问号占位符的汽车。

  1. $stm = $db->prepare('SELECT * FROM cars WHERE id = ?');

问号?是值的占位符。 稍后将这些值添加(绑定)到占位符。

  1. $stm->bindValue(1, 3, SQLITE3_INTEGER);

使用bindValue(),将值 3 绑定到问号占位符。 第一个参数是位置参数,用于标识占位符(可以有多个问号占位符)。

  1. $ php prepared.php
  2. 3 Skoda 9000

This is the output.

具有命名占位符的参数化语句

第二个示例使用带有命名占位符的参数化语句。

prepared2.php

  1. <?php
  2. $db = new SQLite3('test.db');
  3. $stm = $db->prepare('SELECT * FROM cars WHERE id = :id');
  4. $stm->bindValue(':id', 1, SQLITE3_INTEGER);
  5. $res = $stm->execute();
  6. $row = $res->fetchArray(SQLITE3_NUM);
  7. echo "{$row[0]} {$row[1]} {$row[2]}";

我们使用命名的占位符选择特定的汽车。

  1. $stm = $db->prepare('SELECT * FROM cars WHERE id = :id');

命名的占位符以冒号开头。

PHP SQLite3 bind_param

bind_param()将参数绑定到语句变量。 它可以用于处理多行。

bind_param.php

  1. ≪?php
  2. $db = new SQLite3(':memory:');
  3. $db->exec("CREATE TABLE friends(id INTEGER PRIMARY KEY, firstname TEXT, lastname TEXT)");
  4. $stm = $db->prepare("INSERT INTO friends(firstname, lastname) VALUES (?, ?)");
  5. $stm->bindParam(1, $firstName);
  6. $stm->bindParam(2, $lastName);
  7. $firstName = 'Peter';
  8. $lastName = 'Novak';
  9. $stm->execute();
  10. $firstName = 'Lucy';
  11. $lastName = 'Brown';
  12. $stm->execute();
  13. $res = $db->query('SELECT * FROM friends');
  14. while ($row = $res->fetchArray()) {
  15. echo "{$row[0]} {$row[1]} {$row[2]}\n";
  16. }

在示例中,我们将两行插入到带有参数化语句的表中。 要绑定占位符,我们使用bind_param()方法。

  1. $ php bind_param.php
  2. 1 Peter Novak
  3. 2 Lucy Brown

This is the output.

PHP SQLite3 元数据

元数据是有关数据库中数据的信息。 SQLite 中的元数据包含有关表和列的信息,我们在其中存储数据。 受 SQL 语句影响的行数是元数据。 结果集中返回的行数和列数也属于元数据。

可以使用特定的 PHP SQLite3 方法,PRAGMA命令或通过查询 SQLite 系统sqlite_master表来获取 SQLite 中的元数据。

num_of_columns.php

  1. <?php
  2. $db = new SQLite3('test.db');
  3. $res = $db->query("SELECT * FROM cars WHERE id = 1");
  4. $cols = $res->numColumns();
  5. echo "There are {$cols} columns in the result set\n";

numColumns()返回结果集中的列数。

  1. $ php num_of_columns.php
  2. There are 3 columns in the result set

This is the output.

column_names.php

  1. <?php
  2. $db = new SQLite3('test.db');
  3. $res = $db->query("PRAGMA table_info(cars)");
  4. while ($row = $res->fetchArray(SQLITE3_NUM)) {
  5. echo "{$row[0]} {$row[1]} {$row[2]}\n";
  6. }

在此示例中,我们发出PRAGMA table_info(tableName)命令以获取有关cars表的一些元数据信息。

  1. $res = $db->query("PRAGMA table_info(cars)");

PRAGMA table_info(tableName)命令为cars表中的每一列返回一行。 结果集中的列包括列顺序号,列名称,数据类型,该列是否可以为NULL以及该列的默认值。

  1. while ($row = $res->fetchArray(SQLITE3_NUM)) {
  2. echo "{$row[0]} {$row[1]} {$row[2]}\n";
  3. }

根据提供的信息,我们打印列顺序号,列名称和列数据类型。

  1. $ php column_names.php
  2. 0 id INTEGER
  3. 1 name TEXT
  4. 2 price INT

This is the output of the example.

在下面的示例中,我们打印cars表中的所有行及其列名。

column_names2.php

  1. <?php
  2. $db = new SQLite3('test.db');
  3. $res = $db->query("SELECT * FROM cars");
  4. $col1 = $res->columnName(1);
  5. $col2 = $res->columnName(2);
  6. $header = sprintf("%-10s %s\n", $col1, $col2);
  7. echo $header;
  8. while ($row = $res->fetchArray()) {
  9. $line = sprintf("%-10s %s\n", $row[1], $row[2]);
  10. echo $line;
  11. }

我们还将cars表的内容与列名一起打印到控制台。 记录与列名对齐。

  1. $col1 = $res->columnName(1);

columnName()返回第 n 列的名称。

  1. $header = sprintf("%-10s %s\n", $col1, $col2);
  2. echo $header;

这些行打印cars表的两个列名。

  1. while ($row = $res->fetchArray()) {
  2. $line = sprintf("%-10s %s\n", $row[1], $row[2]);
  3. echo $line;
  4. }

我们使用while循环打印行。 数据与列名对齐。

  1. $ php column_names2.php
  2. name price
  3. Audi 52642
  4. Mercedes 57127
  5. Skoda 9000
  6. Volvo 29000
  7. Bentley 350000
  8. Citroen 21000
  9. Hummer 41400
  10. Volkswagen 21600

This is the output.

在下一个示例中,我们列出test.db数据库中的所有表。

list_tables.php

  1. <?php
  2. $db = new SQLite3('test.db');
  3. $res = $db->query("SELECT name FROM sqlite_master WHERE type='table'");
  4. while ($row = $res->fetchArray(SQLITE3_NUM)) {
  5. echo "{$row[0]}\n";
  6. }

该代码示例将指定数据库中的所有可用表打印到终端。

  1. $res = $db->query("SELECT name FROM sqlite_master WHERE type='table'");

表名存储在系统sqlite_master表中。

  1. $ php list_tables.php
  2. cars
  3. images

这些是我们系统上的表。

changes()返回由最新 SQL 语句修改,插入或删除的数据库行数。

changes.php

  1. <?php
  2. $db = new SQLite3(':memory:');
  3. $db->exec("CREATE TABLE friends(id INTEGER PRIMARY KEY, name TEXT)");
  4. $db->exec("INSERT INTO friends(name) VALUES ('Tom')");
  5. $db->exec("INSERT INTO friends(name) VALUES ('Rebecca')");
  6. $db->exec("INSERT INTO friends(name) VALUES ('Jim')");
  7. $db->exec("INSERT INTO friends(name) VALUES ('Robert')");
  8. $db->exec('DELETE FROM friends');
  9. $changes = $db->changes();
  10. echo "The DELETE statement removed $changes rows";

该示例返回已删除的行数。

  1. $ php changes.php
  2. The DELETE statement removed 4 rows

This is the output.

PHP SQLite3 PDO 示例

PHP 数据对象(PDO)定义了用于访问 PHP 中的数据库的轻量级接口。 它提供了一个数据访问抽象层,用于在 PHP 中使用数据库。 它定义了用于各种数据库系统的一致 API。

PHP PDO 是一个内置库; 我们不需要安装它。

list_tables.php

  1. <?php
  2. $pdo = new PDO('sqlite:test.db');
  3. $stm = $pdo->query("SELECT * FROM cars");
  4. $rows = $stm->fetchAll(PDO::FETCH_NUM);
  5. foreach($rows as $row) {
  6. printf("$row[0] $row[1] $row[2]\n");
  7. }

该示例使用 PHP PDO 获取所有表行。

Dibi 的例子

PHP Dibi 是用于 PHP 的小型智能数据库层。

  1. $ composer req dibi/dibi

我们安装库。

fetch_cars.php

  1. <?php
  2. require('vendor/autoload.php');
  3. $db = dibi::connect([
  4. 'driver' => 'sqlite',
  5. 'database' => 'test.db',
  6. ]);
  7. $rows = $db->query('SELECT * FROM cars');
  8. foreach ($rows as $row) {
  9. $id = $row->id;
  10. $name = $row->name;
  11. $price = $row->price;
  12. echo "$id $name $price \n";
  13. }

该示例从cars表中提取所有行。

Doctrine DBAL 示例

Doctrine 是一组 PHP 库,主要致力于在 PHP 中提供持久性服务。 它的主要项目是对象关系映射器(ORM)和数据库抽象层(DBAL)。

  1. $ composer req doctrine/dbal

我们安装 Doctrine DBAL 包。

fetch_cars.php

  1. <?php
  2. require_once "vendor/autoload.php";
  3. use Doctrine\DBAL\DriverManager;
  4. use Doctrine\DBAL\FetchMode;
  5. $attrs = ['driver' => 'pdo_sqlite', 'path' => 'test.db'];
  6. $conn = DriverManager::getConnection($attrs);
  7. $queryBuilder = $conn->createQueryBuilder();
  8. $queryBuilder->select('*')->from('cars');
  9. $stm = $queryBuilder->execute();
  10. $rows = $stm->fetchAll(FetchMode::NUMERIC);
  11. foreach ($rows as $row) {
  12. echo "{$row[0]} {$row[1]} {$row[2]}\n";
  13. }

该示例使用 Doctrine DBAL QueryBuildercars表中检索所有行。

这是 PHP SQLite3 教程。 您可能也对以下相关教程感兴趣: Doctrine QueryBuilder教程PHP PDO 教程PHP 教程,或列出所有 PHP 教程