SQLite3::setAuthorizer

(PHP 8)

SQLite3::setAuthorizer配置一个回调作为授权器,以限制语句可以执行的操作

描述

public SQLite3::setAuthorizer(?callable $callback): bool

设置一个回调,SQLite 将在每次执行操作(读取、删除、更新等)时调用它。当从不受信任的来源准备 SQL 语句时,这将用于确保 SQL 语句不会尝试访问它们无权查看的数据,或者尝试执行破坏数据库的恶意语句。例如,应用程序可能允许用户输入任意 SQL 查询以供数据库评估。但应用程序不希望用户能够对数据库进行任意更改。然后,可以在准备用户输入的 SQL 时设置授权器,以禁止除 SELECT 语句以外的所有操作。

授权器回调可能会为 SQLite 准备的每个语句调用多次。一个 SELECTUPDATE 查询将为要读取或更新的每个列调用授权器。

授权器使用最多五个参数调用。第一个参数始终给出,是一个 int(操作代码),与 SQLite3 中的常量匹配。其他参数仅在某些操作中传递。下表根据操作描述了第二个和第三个参数

操作代码和参数列表
操作 第二个参数 第三个参数
SQLite3::CREATE_INDEX索引名称表名称
SQLite3::CREATE_TABLE表名称null
SQLite3::CREATE_TEMP_INDEX索引名称表名称
SQLite3::CREATE_TEMP_TABLE表名称null
SQLite3::CREATE_TEMP_TRIGGER触发器名称表名称
SQLite3::CREATE_TEMP_VIEW视图名称null
SQLite3::CREATE_TRIGGER触发器名称表名称
SQLite3::CREATE_VIEW视图名称null
SQLite3::DELETE表名称null
SQLite3::DROP_INDEX索引名称表名称
SQLite3::DROP_TABLE表名称null
SQLite3::DROP_TEMP_INDEX索引名称表名称
SQLite3::DROP_TEMP_TABLE表名称null
SQLite3::DROP_TEMP_TRIGGER触发器名称表名称
SQLite3::DROP_TEMP_VIEW视图名称null
SQLite3::DROP_TRIGGER触发器名称表名称
SQLite3::DROP_VIEW视图名称null
SQLite3::INSERT表名称null
SQLite3::PRAGMAPragma 名称传递给 pragma 的第一个参数,或 null
SQLite3::READ表名称列名称
SQLite3::SELECTnullnull
SQLite3::TRANSACTION操作null
SQLite3::UPDATE表名称列名称
SQLite3::ATTACH文件名null
SQLite3::DETACH数据库名称null
SQLite3::ALTER_TABLE数据库名称表名称
SQLite3::REINDEX索引名称null
SQLite3::ANALYZE表名称null
SQLite3::CREATE_VTABLE表名称模块名称
SQLite3::DROP_VTABLE表名称模块名称
SQLite3::FUNCTIONnull函数名称
SQLite3::SAVEPOINT操作保存点名称
SQLite3::RECURSIVEnullnull

如果适用,第 4 个参数将是数据库的名称("main""temp" 等)。

授权器回调的第 5 个参数是负责访问尝试的最内层触发器或视图的名称,或者如果此访问尝试直接来自顶级 SQL 代码,则为 null

当回调返回 SQLite3::OK 时,这意味着请求的操作被接受。当回调返回 SQLite3::DENY 时,触发授权器的调用将失败,并显示一条错误消息,解释访问被拒绝的原因。

如果操作代码是 SQLite3::READ 并且回调返回 SQLite3::IGNORE,则准备好的语句将被构造以在要读取的表列的位置替换为 null 值(如果返回 SQLite3::OK)。SQLite3::IGNORE 返回值可用于拒绝不受信任的用户访问表的单个列。

当表被 SELECT 引用,但没有从该表中提取任何列值(例如在类似 "SELECT count(*) FROM table" 的查询中)时,SQLite3::READ 授权器回调将为此表调用一次,并使用一个空字符串作为列名称。

如果操作代码是 SQLite3::DELETE 并且回调返回 SQLite3::IGNORE,则 DELETE 操作将继续进行,但截断优化将被禁用,并且所有行将被单独删除。

一次只能在一个数据库连接上设置单个授权器。对 SQLite3::setAuthorizer() 的每次调用都会覆盖之前的调用。通过安装 null 回调来禁用授权器。默认情况下,授权器处于禁用状态。

授权器回调不得执行任何会修改调用授权器回调的数据库连接的操作。

请注意,授权器仅在准备语句时调用,而不是在执行语句时调用。

有关更多详细信息,请参阅 » SQLite3 文档.

参数

callback

要调用的 callable

如果传递 null,这将禁用当前的授权器回调。

返回值

成功时返回 true,失败时返回 false

错误/异常

此方法不会抛出任何错误,但如果启用了授权器并返回无效值,则语句准备将抛出错误(或异常,具体取决于使用 SQLite3::enableExceptions() 方法)。

示例

示例 #1 SQLite3::setAuthorizer() 示例

这仅允许访问读取操作,并且仅返回 users 表的某些列。其他列将被替换为 null

<?php
$db
= new SQLite3('data.sqlite');
$db->exec('CREATE TABLE users (id, name, password);');
$db->exec('INSERT INTO users VALUES (1, \'Pauline\', \'Snails4eva\');');

$allowed_columns = ['id', 'name'];

$db->setAuthorizer(function (int $action, ...$args) use ($allowed_columns) {
if (
$action === SQLite3::READ) {
list(
$table, $column) = $args;

if (
$table === 'users' && in_array($column, $allowed_columns) {
return
SQLite3::OK;
}

return
SQLite3::IGNORE;
}

return
SQLite3::DENY;
});

print_r($db->querySingle('SELECT * FROM users WHERE id = 1;'));

以上示例将输出

Array
(
    [id] => 1
    [name] => Pauline
    [password] =>
)
添加笔记

用户贡献的笔记

此页面没有用户贡献的笔记。
To Top