PHP Conference Japan 2024

SQLite3::setAuthorizer

(PHP 8)

SQLite3::setAuthorizer設定一個回呼函式作為授權器,以限制敘述句可以執行的操作

說明

公開 SQLite3::setAuthorizer(?可呼叫 $callback): 布林值

設定一個回呼函式,SQLite 每次執行動作(讀取、刪除、更新等)時都會呼叫它。當從不受信任的來源準備 SQL 陳述式時,可以使用此函式來確保 SQL 陳述式不會嘗試存取它們不允許看到的資料,或者不會嘗試執行損壞資料庫的惡意陳述式。例如,應用程式可能允許使用者輸入任意 SQL 查詢以供資料庫評估。但應用程式不希望使用者能夠對資料庫進行任意更改。然後,可以在準備使用者輸入的 SQL 時設置一個授權器,除了 SELECT 陳述式外,其他所有操作都不允許。

對於 SQLite 準備的每個陳述式,授權器回呼函式可能會被呼叫多次。`SELECT` 或 `UPDATE` 查詢會針對每個將被讀取或更新的欄位呼叫授權器。

授權器會以最多五個參數被呼叫。第一個參數始終會提供,是一個 整數(動作代碼),與 `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

第四個參數將是資料庫的名稱(`main`、`temp` 等),如果適用。

授權器回呼函式的第五個參數是負責存取嘗試的最內層觸發器或檢視的名稱,如果此存取嘗試直接來自頂層 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

要被呼叫的 可呼叫 函式。

如果傳入 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