这是针对SQLite版本3数据库的PHP编程教程。它涵盖了使用PHP语言进行SQLite编程的基础知识。
要使用本教程,我们必须在系统上安装PHPCLI。
要使用SQLite数据库,我们可以安装sqlite3
命令行工具或SQLite浏览器GUI。
$ php -v PHP 8.1.2 (cli) (built: Jun 13 2022 13:52:54) (NTS) Copyright (c) The PHP Group Zend Engine v4.1.2, Copyright (c) Zend Technologies with Zend OPcache v8.1.2, Copyright (c), by Zend Technologies
在本教程中,我们使用PHP8.1.2。
$ sudo apt install php8.1-sqlite3
我们需要为PHP安装SQLite3模块。
... ;extension=sockets extension=sqlite3 ;extension=tidy ...
我们可能需要在php.ini
文件中启用扩展。在Debian系统上,该扩展在安装php8.1-sqlite3
后会自动启用。该扩展在/etc/php/8.1/mods-available/sqlite3.ini
中启用。
SQLite
SQLite是一个嵌入式关系数据库引擎。文档称它为自包含、无服务器、零配置和事务性SQL数据库引擎。它非常受欢迎,如今在全球范围内使用了数亿册。多种编程语言内置了对SQLite的支持,包括PHP和Python。
创建SQLite数据库
我们使用sqlite3
命令行工具来创建一个新的数据库。
$ sqlite3 test.db SQLite version 3.37.2 2022-01-06 13:25:41 Enter ".help" for usage hints. sqlite>
我们为sqlite3
工具提供了一个参数;test.db
是数据库名称。它是我们磁盘上的一个文件。如果存在,则将其打开。如果没有,则创建它。
sqlite> .tables sqlite> .exit $ ls test.db
.tables
命令给出了test.db
数据库中的表列表。当前没有表。.exit
命令终止sqlite3
命令行工具的交互式会话。ls
命令显示当前工作目录的内容。我们可以看到test.db
文件。所有数据都将存储在这个文件中。
PHPSQLite3版本示例
在下面的例子中,我们获取了SQLite数据库的版本。
<?php $ver = SQLite3::version(); echo $ver['versionString'] . "\n"; echo $ver['versionNumber'] . "\n"; var_dump($ver);
SQLite3::version
返回SQLite数据库的版本。
$ php version.php 3.37.2 3037002 array(2) { ["versionString"]=> string(6) "3.37.2" ["versionNumber"]=> int(3037002) }
这是输出。
<?php $db = new SQLite3('test.db'); $version = $db->querySingle('SELECT SQLITE_VERSION()'); echo $version . "\n";
程序返回SQLite数据库的当前版本。这次我们执行了SELECTSQLITE_VERSION
语句。
$db = new SQLite3('test.db');
我们创建一个SQLite3对象并打开一个SQLite3数据库连接。
$version = $db->querySingle('SELECT SQLITE_VERSION()');
querySingle
执行查询并返回单个结果。
$ php version2.php 3.37.2
这是输出。
PHPSQLite3执行
exec
对给定的数据库执行无结果查询。
<?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
表并向表中插入八行。
$db->exec("CREATE TABLE cars(id INTEGER PRIMARY KEY, name TEXT, price INT)");
此SQL语句创建一个新的cars
表。该表有三列。请注意,在SQLite数据库中,INTEGERPRIMARYKEY
列是自动递增的。
$db->exec("INSERT INTO cars(name, price) VALUES('Audi', 52642)"); $db->exec("INSERT INTO cars(name, price) VALUES('Mercedes', 57127)");
这两行将两辆汽车插入表中。
sqlite> .mode column sqlite> .headers on
我们用sqlite3
工具验证写入的数据。首先我们修改数据在控制台中的显示方式。我们使用列模式并打开标题。
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
表的数据。
PHPSQLite3lastInsertRowID
有时候,我们需要确定最后插入的行的Id。在PHPSQLite3中,我们使用lastInsertRowID
方法。
<?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会自动递增。
$db->exec("CREATE TABLE friends(id INTEGER PRIMARY KEY, name TEXT)");
在SQLite3中,INTEGERPRIMARYKEY
列是自动递增的。还有一个AUTOINCREMENT
关键字。在INTEGERPRIMARYKEYAUTOINCREMENT
中使用时,会使用略微不同的Id创建算法。
$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
表中。
$last_row_id = $db->lastInsertRowID();
我们使用lastInsertRowID
获取最后插入的行ID。
$ php last_rowid.php The last inserted row Id is 4
我们看到程序的输出。
PHPSQLite3查询
query
方法执行SQL查询并返回结果对象。
<?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
表中检索所有数据。
$res = $db->query('SELECT * FROM cars');
此SQL语句从cars
表中选择所有数据。
while ($row = $res->fetchArray()) {
fetchArray
将结果行检索为关联数组或数字索引数组或两者(默认为两者)。如果没有更多行,则返回false
。
$ 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
这是示例的输出。
PHPSQLite3转义字符串
escapeString
返回已正确转义的字符串。
<?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 escape_string.php string(41) "SELECT name FROM cars WHERE name = 'Audi'" string(43) "SELECT name FROM cars WHERE name = ''Audi''"
这是示例的输出。
PHPSQLite3参数化语句
SQL语句通常是动态构建的。用户提供了一些输入,这个输入被内置到语句中。每次处理来自用户的输入时,我们都必须谨慎。它有一些严重的安全隐患。动态构建SQL语句的推荐方法是使用参数绑定。
参数化查询是用prepare
创建的;它准备执行SQL语句并返回语句对象。
PHPSQLite3有bindParam
和bindValue
方法将值绑定到占位符。它允许将数据绑定到问号或命名占位符。
带问号的参数化语句
在第一个示例中,我们使用问号的语法。
<?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]}";
我们使用问号占位符选择汽车。
$stm = $db->prepare('SELECT * FROM cars WHERE id = ?');
问号?
是值的占位符。这些值稍后添加(绑定)到占位符。
$stm->bindValue(1, 3, SQLITE3_INTEGER);
使用bindValue
,我们将值3绑定到问号占位符。第一个参数是位置参数,标识占位符(可以有多个问号占位符)。
$ php prepared.php 3 Skoda 9000
这是输出。
带有命名占位符的参数化语句
第二个示例使用带命名占位符的参数化语句。
<?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]}";
我们使用命名占位符选择一辆特定的汽车。
$stm = $db->prepare('SELECT * FROM cars WHERE id = :id');
命名占位符以冒号字符开头。
PHPSQLite3绑定参数
bind_param
将参数绑定到语句变量。它可用于处理多行。
<?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 bind_param.php 1 Peter Novak 2 Lucy Brown
这是输出。
PHPSQLite3元数据
元数据是关于数据库中数据的信息。SQLite中的元数据包含有关我们存储数据的表和列的信息。受SQL语句影响的行数是元数据。结果集中返回的行数和列数也属于元数据。
SQLite中的元数据可以使用特定的PHPSQLite3方法、PRAGMA
命令或通过查询SQLite系统sqlite_master
表来获取。
<?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 num_of_columns.php There are 3 columns in the result set
这是输出。
<?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"; }
在此示例中,我们发出PRAGMAtable_info(tableName)
命令来获取有关我们的cars
表的一些元数据信息。
$res = $db->query("PRAGMA table_info(cars)");
PRAGMAtable_info(tableName)
命令为cars
表中的每一列返回一行。结果集中的列包括列序号、列名、数据类型、列是否可以为NULL
,以及列的默认值。
while ($row = $res->fetchArray(SQLITE3_NUM)) { echo "{$row[0]} {$row[1]} {$row[2]}\n"; }
根据提供的信息,我们打印列序号、列名称和列数据类型。
$ php column_names.php 0 id INTEGER 1 name TEXT 2 price INT
这是示例的输出。
在下面的示例中,我们打印cars
表中的所有行及其列名。
<?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
表的内容连同列名一起打印到控制台。记录与列名对齐。
$col1 = $res->columnName(1);
columnName
返回第n列的名称。
$header = sprintf("%-10s %s\n", $col1, $col2); echo $header;
这些行打印cars
表的两个列名。
while ($row = $res->fetchArray()) { $line = sprintf("%-10s %s\n", $row[1], $row[2]); echo $line; }
我们使用while循环打印行。数据与列名对齐。
$ php column_names2.php name price Audi 52642 Mercedes 57127 Skoda 9000 Volvo 29000 Bentley 350000 Citroen 21000 Hummer 41400 Volkswagen 21600
这是输出。
在下一个示例中,我们列出了test.db
数据库中的所有表。
<?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"; }
代码示例将指定数据库中的所有可用表打印到终端。
$res = $db->query("SELECT name FROM sqlite_master WHERE type='table'");
表名存储在系统sqlite_master
表中。
$ php list_tables.php cars images
这些是我们系统上的表。
changes
返回被最近的SQL语句修改、插入或删除的数据库行数。
<?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 changes.php The DELETE statement removed 4 rows
这是输出。
PHPSQLite3PDO示例
PHP数据对象(PDO)定义了一个轻量级接口,用于访问PHP中的数据库。它提供了一个数据访问抽象层,用于在PHP中使用数据库。它定义了用于处理各种数据库系统的一致API。
PHPPDO是一个内置库;我们不需要安装它。
<?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"); }
该示例使用PHPPDO获取所有表行。
滴滴示例
PHPDibi是一个用于PHP的小型智能数据库层。
$ composer req dibi/dibi
我们安装库。
<?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
表中获取所有行。
DoctrineDBAL示例
Doctrine是一组PHP库,主要专注于在PHP中提供持久性服务。它的主要项目是对象关系映射器(ORM)和数据库抽象层(DBAL)。
$ composer req doctrine/dbal
我们安装DoctrineDBAL包。
<?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"; }
该示例使用DoctrineDBALQueryBuilder从cars
表中检索所有行。
这是PHPSQLite3教程。
列出所有PHP教程。