使用PHP打造轻量级单文件SQLite数据库管理工具
今天闲逛时发现一篇技术文章,非常不错,就转过来了。
以下是全文:
先声明一下,这是我自己内网使用的一个简单的管理工具,所以安全性方面我肯定是没有测试的~ 如果你要放在公网,请添加相关的权限认证及sql防注入等处理
在开发过程中,我们经常需要一个简单易用的数据库管理工具来快速查看和操作数据库。本文将介绍如何使用PHP为SQLite开发一款强大的数据库管理工具,并将其部署在PHP环境中,以便于快速访问和使用。
SQLite是一个轻量级的嵌入式数据库,非常适合用于小型项目或原型开发。然而,SQLite自带的命令行工具虽然功能强大,但对于非技术人员来说,使用起来并不直观。因此,我们决定使用PHP来构建一个简单的Web界面,以便于用户通过浏览器来管理和操作SQLite数据库。
先预览一下(嘿嘿~丑是丑了点~但已经完全够用了~~
):
功能概述
我们的SQLite数据库管理工具具备以下功能:
-
表管理:
- 列出数据库中的所有表。
- 创建新表。
- 删除现有表。
-
字段管理:
- 查看表结构。
- 添加新字段。
- 删除现有字段。
- 编辑字段属性(字段名、类型、默认值等)。
-
记录管理:
- 删除表中的记录。
-
SQL执行器:
- 执行自定义SQL查询。
- 显示查询结果。
代码实现
以下是我们的PHP代码实现,展示了如何使用PDO连接SQLite数据库,并实现上述功能,文件名为db.php
,就一个文件~
setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
if (!$db) {
die('数据库连接失败,请检查配置。');
}
// 获取表列表
function listTables(PDO $db) {
$stmt = $db->query("SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%'");
return $stmt->fetchAll(PDO::FETCH_COLUMN);
}
// 获取表结构
function getTableStructure(PDO $db, $tableName) {
$stmt = $db->query("PRAGMA table_info($tableName)");
return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
// 动态处理表单操作
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$action = $_POST['action'] ?? '';
$table = $_POST['table'] ?? '';
if ($action === 'create-table') {
$tableName = $_POST['table_name'];
$db->exec("CREATE TABLE $tableName (id INTEGER PRIMARY KEY AUTOINCREMENT)");
header("Location: db.php?table=$tableName");
exit();
}
if ($action === 'delete-table') {
$db->exec("DROP TABLE $table");
header("Location: db.php");
exit();
}
if ($action === 'add-field') {
$fieldName = $_POST['field_name'];
$fieldType = $_POST['field_type'];
$defaultValue = $_POST['default_value'] ?? null;
// 构造字段定义
$fieldDefinition = "$fieldName $fieldType";
if ($defaultValue !== null && $defaultValue !== '') {
// 如果默认值是字符串,需要添加引号
$defaultValue = is_numeric($defaultValue) ? $defaultValue : "'$defaultValue'";
$fieldDefinition .= " DEFAULT $defaultValue";
}
// 添加字段
$db->exec("ALTER TABLE $table ADD COLUMN $fieldDefinition");
header("Location: db.php?table=$table");
exit();
}
if ($action === 'delete-field') {
$fieldName = $_POST['field_name'];
// 获取原表结构
$structure = getTableStructure($db, $table);
// 构造新表的字段定义,排除要删除的字段
$columns = [];
$columnsForInsert = [];
foreach ($structure as $column) {
if ($column['name'] !== $fieldName) {
$columnDefinition = $column['name'] . ' ' . $column['type'];
if ($column['notnull']) {
$columnDefinition .= ' NOT NULL';
}
if ($column['dflt_value'] !== null) {
// 检查并处理默认值
if (is_numeric($column['dflt_value'])) {
$defaultValue = $column['dflt_value']; // 数字直接使用
} else {
// 如果不是数字且未包裹引号,则包裹一次单引号
$defaultValue = trim($column['dflt_value'], "'"); // 去掉可能存在的多余引号
$defaultValue = "'" . str_replace("'", "''", $defaultValue) . "'";
}
$columnDefinition .= " DEFAULT $defaultValue";
}
if ($column['pk']) {
$columnDefinition .= ' PRIMARY KEY';
}
$columns[] = $columnDefinition;
$columnsForInsert[] = $column['name'];
}
}
$newColumnsStr = implode(', ', $columns);
$columnsForInsertStr = implode(', ', $columnsForInsert);
// 创建新表并迁移数据
$db->exec("CREATE TABLE ${table}_new ($newColumnsStr)");
$db->exec("INSERT INTO ${table}_new ($columnsForInsertStr) SELECT $columnsForInsertStr FROM $table");
// 删除旧表并重命名新表
$db->exec("DROP TABLE $table");
$db->exec("ALTER TABLE ${table}_new RENAME TO $table");
header("Location: db.php?table=$table");
exit();
}
if ($action === 'edit-field') {
$oldFieldName = $_POST['old_field_name'];
$newFieldName = $_POST['new_field_name'];
$newFieldType = $_POST['new_field_type'];
$defaultValue = $_POST['default_value'] ?? null;
// 获取表结构,创建新的表结构
$structure = getTableStructure($db, $table);
$columns = [];
$columnsForInsert = [];
foreach ($structure as $column) {
if ($column['name'] === $oldFieldName) {
// 针对被编辑的字段,使用表单中提交的值
$fieldDefinition = "$newFieldName $newFieldType";
// 设置新默认值,仅对被修改字段生效
if ($defaultValue !== null && $defaultValue !== '') {
// 检查默认值是否已被包裹引号
if (!is_numeric($defaultValue) && !preg_match("/^'.*'$/", $defaultValue)) {
// 为字符串添加引号并转义内部引号
$defaultValue = "'" . str_replace("'", "''", $defaultValue) . "'";
}
$fieldDefinition .= " DEFAULT $defaultValue";
}
// 保留字段的非空和主键约束
if ($column['notnull']) {
$fieldDefinition .= " NOT NULL";
}
if ($column['pk']) {
$fieldDefinition .= " PRIMARY KEY";
}
$columns[] = $fieldDefinition;
$columnsForInsert[] = $newFieldName;
} else {
// 对于未修改的字段,完全保留其原始定义
$fieldDefinition = $column['name'] . ' ' . $column['type'];
if ($column['dflt_value'] !== null) {
// 仅保留字段的原始默认值,不改变
$originalDefaultValue = is_numeric($column['dflt_value'])
? $column['dflt_value']
: "'" . str_replace("'", "''", trim($column['dflt_value'], "'")) . "'";
$fieldDefinition .= " DEFAULT $originalDefaultValue";
}
// 保留非空和主键约束
if ($column['notnull']) {
$fieldDefinition .= " NOT NULL";
}
if ($column['pk']) {
$fieldDefinition .= " PRIMARY KEY";
}
$columns[] = $fieldDefinition;
$columnsForInsert[] = $column['name'];
}
}
$newColumnsStr = implode(', ', $columns);
$columnsForInsertStr = implode(', ', $columnsForInsert);
// 创建新表并迁移数据
$db->exec("CREATE TABLE ${table}_new ($newColumnsStr)");
$db->exec("INSERT INTO ${table}_new ($columnsForInsertStr) SELECT $columnsForInsertStr FROM $table");
// 删除旧表并重命名新表
$db->exec("DROP TABLE $table");
$db->exec("ALTER TABLE ${table}_new RENAME TO $table");
header("Location: db.php?table=$table");
exit();
}
if ($action === 'delete-record') {
$id = $_POST['id'];
$db->exec("DELETE FROM $table WHERE id = $id");
header("Location: db.php?table=$table");
exit();
}
if (isset($_POST['sql_query'])) {
$sqlQuery = trim($_POST['sql_query']);
try {
$stmt = $db->query($sqlQuery);
if ($stmt) {
$queryResults = $stmt->fetchAll(PDO::FETCH_ASSOC);
} else {
$queryResults = [];
}
} catch (Exception $e) {
$queryError = $e->getMessage();
}
}
}
$tables = listTables($db);
$currentTable = $_GET['table'] ?? null;
$tableStructure = $currentTable ? getTableStructure($db, $currentTable) : [];
} catch (Exception $e) {
die('数据库操作失败: ' . $e->getMessage());
}
?>
篇幅有限,只展示了纯 php 部分代码,可点击文末的链接下载文件查看全部代码。
本文转自:https://www.lvtao.net/dev/php-sqlite-manage-tool.html
下载:db.zip
本文由[ Dazeng ]在[ 曾先生记事本 ]发布,转载请注明出处。