ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
# PHP SQLite3 教程 > 原文: [https://zetcode.com/php/sqlite3/](https://zetcode.com/php/sqlite3/) 这是针对 SQLite 版本 3 数据库的 PHP 编程教程。 它涵盖了使用 PHP 语言进行 SQLite 编程的基础。 要使用本教程,我们必须在系统上安装 PHP CLI。 为了使用 SQLite 数据库,我们可以安装`sqlite3`命令行工具或 SQLite 浏览器 GUI。 ```php $ php -v PHP 7.2.11 (cli) (built: Oct 10 2018 02:39:52) ( ZTS MSVC15 (Visual C++ 2017) x86 ) Copyright (c) 1997-2018 The PHP Group Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies ``` 在本教程中,我们使用 PHP 7.2.11。 ```php ... ;extension=sockets extension=sqlite3 ;extension=tidy ... ``` SQLite 随 PHP 一起提供; 我们不需要安装它。 我们必须在`php.ini`文件中启用 sqlite3 扩展。 ## SQLite SQLite 是嵌入式关系数据库引擎。 该文档称其为自包含,无服务器,零配置和事务型 SQL 数据库引擎。 如今,它在全球使用着数亿册,非常受欢迎。 几种编程语言都内置了对 SQLite 的支持,包括 PHP 和 Python。 ## 创建 SQLite 数据库 我们使用`sqlite3`命令行工具创建一个新数据库。 ```php $ sqlite3 test.db SQLite version 3.27.2 2019-02-25 16:06:06 Enter ".help" for usage hints. sqlite> ``` 我们为`sqlite3`工具提供了一个参数; `test.db`是数据库名称。 这是我们磁盘上的文件。 如果存在,则将其打开。 如果不是,则创建它。 ```php sqlite> .tables sqlite> .exit $ ls test.db ``` `.tables`命令提供`test.db`数据库中的表的列表。 当前没有表格。 `.exit`命令终止`sqlite3`命令行工具的交互式会话。 `ls`命令显示当前工作目录的内容。 我们可以看到`test.db`文件。 所有数据将存储在该单个文件中。 ## PHP SQLite3 版本示例 在以下示例中,我们获得了 SQLite 数据库的版本。 `version.php` ```php <?php $ver = SQLite3::version(); echo $ver['versionString'] . "\n"; echo $ver['versionNumber'] . "\n"; var_dump($ver); ``` `SQLite3::version()`返回 SQLite 数据库的版本。 ```php $ php version.php 3.20.1 3020001 array(2) { ["versionString"]=> string(6) "3.20.1" ["versionNumber"]=> int(3020001) } ``` 这是输出。 `version2.php` ```php <?php $db = new SQLite3('test.db'); $version = $db->querySingle('SELECT SQLITE_VERSION()'); echo $version . "\n"; ``` 程序返回 SQLite 数据库的当前版本。 这次我们执行了`SELECT SQLITE_VERSION()`语句。 ```php $db = new SQLite3('test.db'); ``` 我们创建一个 SQLite3 对象并打开一个 SQLite3 数据库连接。 ```php $version = $db->querySingle('SELECT SQLITE_VERSION()'); ``` `querySingle()`执行查询并返回单个结果。 ```php $ php version2.php 3.20.1 ``` This is the output. ## PHP SQLite3 执行 `exec()`对给定的数据库执行无结果查询。 `create_table.php` ```php <?php $db = new SQLite3('test.db'); $db->exec("CREATE TABLE cars(id INTEGER PRIMARY KEY, name TEXT, price INT)"); $db->exec("INSERT INTO cars(name, price) VALUES('Audi', 52642)"); $db->exec("INSERT INTO cars(name, price) VALUES('Mercedes', 57127)"); $db->exec("INSERT INTO cars(name, price) VALUES('Skoda', 9000)"); $db->exec("INSERT INTO cars(name, price) VALUES('Volvo', 29000)"); $db->exec("INSERT INTO cars(name, price) VALUES('Bentley', 350000)"); $db->exec("INSERT INTO cars(name, price) VALUES('Citroen', 21000)"); $db->exec("INSERT INTO cars(name, price) VALUES('Hummer', 41400)"); $db->exec("INSERT INTO cars(name, price) VALUES('Volkswagen', 21600)"); ``` 该程序将创建一个`cars`表,并将八行插入该表中。 ```php $db->exec("CREATE TABLE cars(id INTEGER PRIMARY KEY, name TEXT, price INT)"); ``` 该 SQL 语句创建一个新的`cars`表。 该表有三列。 请注意,在 SQLite 数据库中,`INTEGER PRIMARY KEY`列是自动增加的。 ```php $db->exec("INSERT INTO cars(name, price) VALUES('Audi', 52642)"); $db->exec("INSERT INTO cars(name, price) VALUES('Mercedes', 57127)"); ``` 这两行将两辆车插入表。 ```php sqlite> .mode column sqlite> .headers on ``` 我们使用`sqlite3`工具验证写入的数据。 首先,我们修改数据在控制台中的显示方式。 我们使用列模式并打开标题。 ```php sqlite> select * from cars; id name price ---------- ---------- ---------- 1 Audi 52642 2 Mercedes 57127 3 Skoda 9000 4 Volvo 29000 5 Bentley 350000 6 Citroen 21000 7 Hummer 41400 8 Volkswagen 21600 ``` 这是我们已写入`cars`表的数据。 ## PHP SQLite3 `lastInsertRowID` 有时,我们需要确定最后插入的行的 ID。 在 PHP SQLite3 中,我们使用`lastInsertRowID()`方法。 `last_rowid.php` ```php <?php $db = new SQLite3(':memory:'); $db->exec("CREATE TABLE friends(id INTEGER PRIMARY KEY, name TEXT)"); $db->exec("INSERT INTO friends(name) VALUES ('Tom')"); $db->exec("INSERT INTO friends(name) VALUES ('Rebecca')"); $db->exec("INSERT INTO friends(name) VALUES ('Jim')"); $db->exec("INSERT INTO friends(name) VALUES ('Robert')"); $last_row_id = $db->lastInsertRowID(); echo "The last inserted row Id is $last_row_id"; ``` 我们在内存中创建一个`friends`表。 ID 会自动递增。 ```php $db->exec("CREATE TABLE friends(id INTEGER PRIMARY KEY, name TEXT)"); ``` 在 SQLite3 中,`INTEGER PRIMARY KEY`列自动增加。 还有一个`AUTOINCREMENT`关键字。 在`INTEGER PRIMARY KEY AUTOINCREMENT`中使用时,会使用稍微不同的 ID 创建算法。 ```php $db->exec("CREATE TABLE friends(id INTEGER PRIMARY KEY, name TEXT)"); $db->exec("INSERT INTO friends(name) VALUES ('Tom')"); $db->exec("INSERT INTO friends(name) VALUES ('Rebecca')"); $db->exec("INSERT INTO friends(name) VALUES ('Jim')"); $db->exec("INSERT INTO friends(name) VALUES ('Robert')"); ``` 使用自动增量时,我们必须明确声明列名,而忽略自动增量的列名。 这四个语句在`friends`表中插入四行。 ```php $last_row_id = $db->lastInsertRowID(); ``` 使用`lastInsertRowID()`获得最后插入的行 ID。 ```php $ php last_rowid.php The last inserted row Id is 4 ``` 我们看到了程序的输出。 ## PHP SQLite3 查询 `query()`方法执行 SQL 查询并返回结果对象。 `fetch_all.php` ```php <?php $db = new SQLite3('test.db'); $res = $db->query('SELECT * FROM cars'); while ($row = $res->fetchArray()) { echo "{$row['id']} {$row['name']} {$row['price']} \n"; } ``` 该示例从`cars`表中检索所有数据。 ```php $res = $db->query('SELECT * FROM cars'); ``` 该 SQL 语句从`cars`表中选择所有数据。 ```php while ($row = $res->fetchArray()) { ``` `fetchall()`检索结果行作为关联数组或数字索引数组,或两者都检索(默认为两者)。 如果没有更多行,则返回`false`。 ```php $ php fetch_all.php 1 Audi 52642 2 Mercedes 57127 3 Skoda 9000 4 Volvo 29000 5 Bentley 350000 6 Citroen 21000 7 Hummer 41400 8 Volkswagen 21600 ``` 这是示例的输出。 ## PHP SQLite3 `escapeString` `escapeString()`返回已正确转义的字符串。 `escape_string.php` ```php <?php $db = new SQLite3('test.db'); $sql = "SELECT name FROM cars WHERE name = 'Audi'"; $escaped = SQLite3::escapeString($sql); var_dump($sql); var_dump($escaped); ``` 该示例对查询中的字符串进行转义。 ```php $ php escape_string.php string(41) "SELECT name FROM cars WHERE name = 'Audi'" 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` ```php <?php $db = new SQLite3('test.db'); $stm = $db->prepare('SELECT * FROM cars WHERE id = ?'); $stm->bindValue(1, 3, SQLITE3_INTEGER); $res = $stm->execute(); $row = $res->fetchArray(SQLITE3_NUM); echo "{$row[0]} {$row[1]} {$row[2]}"; ``` 我们选择使用问号占位符的汽车。 ```php $stm = $db->prepare('SELECT * FROM cars WHERE id = ?'); ``` 问号`?`是值的占位符。 稍后将这些值添加(绑定)到占位符。 ```php $stm->bindValue(1, 3, SQLITE3_INTEGER); ``` 使用`bindValue()`,将值 3 绑定到问号占位符。 第一个参数是位置参数,用于标识占位符(可以有多个问号占位符)。 ```php $ php prepared.php 3 Skoda 9000 ``` This is the output. ### 具有命名占位符的参数化语句 第二个示例使用带有命名占位符的参数化语句。 `prepared2.php` ```php <?php $db = new SQLite3('test.db'); $stm = $db->prepare('SELECT * FROM cars WHERE id = :id'); $stm->bindValue(':id', 1, SQLITE3_INTEGER); $res = $stm->execute(); $row = $res->fetchArray(SQLITE3_NUM); echo "{$row[0]} {$row[1]} {$row[2]}"; ``` 我们使用命名的占位符选择特定的汽车。 ```php $stm = $db->prepare('SELECT * FROM cars WHERE id = :id'); ``` 命名的占位符以冒号开头。 ### PHP SQLite3 bind_param `bind_param()`将参数绑定到语句变量。 它可以用于处理多行。 `bind_param.php` ```php ≪?php $db = new SQLite3(':memory:'); $db->exec("CREATE TABLE friends(id INTEGER PRIMARY KEY, firstname TEXT, lastname TEXT)"); $stm = $db->prepare("INSERT INTO friends(firstname, lastname) VALUES (?, ?)"); $stm->bindParam(1, $firstName); $stm->bindParam(2, $lastName); $firstName = 'Peter'; $lastName = 'Novak'; $stm->execute(); $firstName = 'Lucy'; $lastName = 'Brown'; $stm->execute(); $res = $db->query('SELECT * FROM friends'); while ($row = $res->fetchArray()) { echo "{$row[0]} {$row[1]} {$row[2]}\n"; } ``` 在示例中,我们将两行插入到带有参数化语句的表中。 要绑定占位符,我们使用`bind_param()`方法。 ```php $ php bind_param.php 1 Peter Novak 2 Lucy Brown ``` This is the output. ## PHP SQLite3 元数据 元数据是有关数据库中数据的信息。 SQLite 中的元数据包含有关表和列的信息,我们在其中存储数据。 受 SQL 语句影响的行数是元数据。 结果集中返回的行数和列数也属于元数据。 可以使用特定的 PHP SQLite3 方法,`PRAGMA`命令或通过查询 SQLite 系统`sqlite_master`表来获取 SQLite 中的元数据。 `num_of_columns.php` ```php <?php $db = new SQLite3('test.db'); $res = $db->query("SELECT * FROM cars WHERE id = 1"); $cols = $res->numColumns(); echo "There are {$cols} columns in the result set\n"; ``` `numColumns()`返回结果集中的列数。 ```php $ php num_of_columns.php There are 3 columns in the result set ``` This is the output. `column_names.php` ```php <?php $db = new SQLite3('test.db'); $res = $db->query("PRAGMA table_info(cars)"); while ($row = $res->fetchArray(SQLITE3_NUM)) { echo "{$row[0]} {$row[1]} {$row[2]}\n"; } ``` 在此示例中,我们发出`PRAGMA table_info(tableName)`命令以获取有关`cars`表的一些元数据信息。 ```php $res = $db->query("PRAGMA table_info(cars)"); ``` `PRAGMA table_info(tableName)`命令为`cars`表中的每一列返回一行。 结果集中的列包括列顺序号,列名称,数据类型,该列是否可以为`NULL`以及该列的默认值。 ```php while ($row = $res->fetchArray(SQLITE3_NUM)) { echo "{$row[0]} {$row[1]} {$row[2]}\n"; } ``` 根据提供的信息,我们打印列顺序号,列名称和列数据类型。 ```php $ php column_names.php 0 id INTEGER 1 name TEXT 2 price INT ``` This is the output of the example. 在下面的示例中,我们打印`cars`表中的所有行及其列名。 `column_names2.php` ```php <?php $db = new SQLite3('test.db'); $res = $db->query("SELECT * FROM cars"); $col1 = $res->columnName(1); $col2 = $res->columnName(2); $header = sprintf("%-10s %s\n", $col1, $col2); echo $header; while ($row = $res->fetchArray()) { $line = sprintf("%-10s %s\n", $row[1], $row[2]); echo $line; } ``` 我们还将`cars`表的内容与列名一起打印到控制台。 记录与列名对齐。 ```php $col1 = $res->columnName(1); ``` `columnName()`返回第 n 列的名称。 ```php $header = sprintf("%-10s %s\n", $col1, $col2); echo $header; ``` 这些行打印`cars`表的两个列名。 ```php while ($row = $res->fetchArray()) { $line = sprintf("%-10s %s\n", $row[1], $row[2]); echo $line; } ``` 我们使用`while`循环打印行。 数据与列名对齐。 ```php $ php column_names2.php name price Audi 52642 Mercedes 57127 Skoda 9000 Volvo 29000 Bentley 350000 Citroen 21000 Hummer 41400 Volkswagen 21600 ``` This is the output. 在下一个示例中,我们列出`test.db`数据库中的所有表。 `list_tables.php` ```php <?php $db = new SQLite3('test.db'); $res = $db->query("SELECT name FROM sqlite_master WHERE type='table'"); while ($row = $res->fetchArray(SQLITE3_NUM)) { echo "{$row[0]}\n"; } ``` 该代码示例将指定数据库中的所有可用表打印到终端。 ```php $res = $db->query("SELECT name FROM sqlite_master WHERE type='table'"); ``` 表名存储在系统`sqlite_master`表中。 ```php $ php list_tables.php cars images ``` 这些是我们系统上的表。 `changes()`返回由最新 SQL 语句修改,插入或删除的数据库行数。 `changes.php` ```php <?php $db = new SQLite3(':memory:'); $db->exec("CREATE TABLE friends(id INTEGER PRIMARY KEY, name TEXT)"); $db->exec("INSERT INTO friends(name) VALUES ('Tom')"); $db->exec("INSERT INTO friends(name) VALUES ('Rebecca')"); $db->exec("INSERT INTO friends(name) VALUES ('Jim')"); $db->exec("INSERT INTO friends(name) VALUES ('Robert')"); $db->exec('DELETE FROM friends'); $changes = $db->changes(); echo "The DELETE statement removed $changes rows"; ``` 该示例返回已删除的行数。 ```php $ php changes.php The DELETE statement removed 4 rows ``` This is the output. ## PHP SQLite3 PDO 示例 PHP 数据对象(PDO)定义了用于访问 PHP 中的数据库的轻量级接口。 它提供了一个数据访问抽象层,用于在 PHP 中使用数据库。 它定义了用于各种数据库系统的一致 API。 PHP PDO 是一个内置库; 我们不需要安装它。 `list_tables.php` ```php <?php $pdo = new PDO('sqlite:test.db'); $stm = $pdo->query("SELECT * FROM cars"); $rows = $stm->fetchAll(PDO::FETCH_NUM); foreach($rows as $row) { printf("$row[0] $row[1] $row[2]\n"); } ``` 该示例使用 PHP PDO 获取所有表行。 ## Dibi 的例子 PHP Dibi 是用于 PHP 的小型智能数据库层。 ```php $ composer req dibi/dibi ``` 我们安装库。 `fetch_cars.php` ```php <?php require('vendor/autoload.php'); $db = dibi::connect([ 'driver' => 'sqlite', 'database' => 'test.db', ]); $rows = $db->query('SELECT * FROM cars'); foreach ($rows as $row) { $id = $row->id; $name = $row->name; $price = $row->price; echo "$id $name $price \n"; } ``` 该示例从`cars`表中提取所有行。 ## Doctrine DBAL 示例 Doctrine 是一组 PHP 库,主要致力于在 PHP 中提供持久性服务。 它的主要项目是对象关系映射器(ORM)和数据库抽象层(DBAL)。 ```php $ composer req doctrine/dbal ``` 我们安装 Doctrine DBAL 包。 `fetch_cars.php` ```php <?php require_once "vendor/autoload.php"; use Doctrine\DBAL\DriverManager; use Doctrine\DBAL\FetchMode; $attrs = ['driver' => 'pdo_sqlite', 'path' => 'test.db']; $conn = DriverManager::getConnection($attrs); $queryBuilder = $conn->createQueryBuilder(); $queryBuilder->select('*')->from('cars'); $stm = $queryBuilder->execute(); $rows = $stm->fetchAll(FetchMode::NUMERIC); foreach ($rows as $row) { echo "{$row[0]} {$row[1]} {$row[2]}\n"; } ``` 该示例使用 Doctrine DBAL `QueryBuilder`从`cars`表中检索所有行。 这是 PHP SQLite3 教程。 您可能也对以下相关教程感兴趣: [Doctrine `QueryBuilder`教程](/doctrine/querybuilder/), [PHP PDO 教程](/php/pdo/)和 [PHP 教程](/lang/php/),或列出[所有 PHP 教程](/all/#php)。