PHP Conference Japan 2024

SQLite3::createAggregate

(PHP 5 >= 5.3.0, PHP 7, PHP 8)

SQLite3::createAggregate註冊一個 PHP 函式,以用作 SQL 聚合函式

說明

public SQLite3::createAggregate(
    字串 $name,
    可呼叫 $stepCallback,
    可呼叫 $finalCallback,
    整數 $argCount = -1
): 布林值

註冊一個 PHP 函數或使用者自訂函數,使其作為 SQL 聚合函數在 SQL 陳述式中使用。

參數

name

欲建立或重新定義的 SQL 聚合函數名稱。

stepCallback

針對結果集的每一列呼叫的回呼函數。您的 PHP 函數應累加結果並將其儲存在聚合上下文中。

此函數需要定義為

step(
    混合型別 $context,
    整數 $rownumber,
    混合型別 $value,
    混合型別 ...$values
): 混合型別
context

對於第一列為 null;在後續列中,它將具有先前從 step 函數返回的值;您應該使用它來維護聚合狀態。

rownumber

目前的列號。

value

傳遞給聚合函數的第一個參數。

values

傳遞給聚合函數的其他參數。

此函數的返回值將在下次呼叫 step 或 finalize 函數時用作 context 參數。

finalCallback

用於聚合來自每一列的「逐步」資料的回呼函數。處理完所有列後,將呼叫此函數,它應該從聚合上下文中取得資料並返回結果。此回呼函數應返回 SQLite 可理解的類型(即純量類型)。

此函數需要定義為

fini(混合型別 $context, 整數 $rownumber): 混合型別
context

保存最後一次呼叫 step 函數的返回值。

rownumber

永遠為 0

此函數的返回值將用作聚合函數的返回值。

argCount

SQL 聚合函數接受的參數數量。如果此參數為負數,則 SQL 聚合函數可以接受任意數量的參數。

返回值

成功建立聚合函數時返回 true,失敗時返回 false

範例

範例 #1 max_length 聚合函數範例

<?php
$data
= array(
'one',
'two',
'three',
'four',
'five',
'six',
'seven',
'eight',
'nine',
'ten',
);
$db = new SQLite3(':memory:');
$db->exec("CREATE TABLE strings(a)");
// 建立一個名為 strings 的資料表,包含一個欄位 a
$insert = $db->prepare('INSERT INTO strings VALUES (?)');
// 準備一個插入資料的 SQL 語句
foreach (
$data as $str) {
$insert->bindValue(1, $str);
$insert->execute();
// 將 $data 陣列中的每個字串插入到資料表中
}
$insert = null;
// 釋放準備好的語句

function
max_len_step($context, $rownumber, $string)
{
if (
strlen($string) > $context) {
$context = strlen($string);
}
return
$context;
// 逐步計算最大字串長度
}

function
max_len_finalize($context, $rownumber)
{
return
$context === null ? 0 : $context;
// 返回最終的最大字串長度
}

$db->createAggregate('max_len', 'max_len_step', 'max_len_finalize');
// 建立一個名為 max_len 的聚合函數

var_dump($db->querySingle('SELECT max_len(a) from strings'));
// 查詢並輸出字串的最大長度
?>

以上範例會輸出

int(5)

在此範例中,我們建立一個聚合函式,用於計算表格某欄位中最長字串的長度。 對於每一列,都會呼叫 max_len_step 函式,並傳入一個 $context 參數。 這個 context 參數就像其他 PHP 變數一樣,可以設定為儲存陣列或甚至是物件值。 在此範例中,我們只是用它來儲存目前為止看到的最長長度;如果 $string 的長度比目前的最大值長,我們就更新 context 來儲存這個新的最大長度。

處理完所有列之後,SQLite 會呼叫 max_len_finalize 函式來決定聚合結果。 在這裡,我們可以根據在 $context 中找到的資料執行一些計算。 然而,在我們的簡單範例中,我們在查詢過程中一直在計算結果,因此我們只需要回傳 context 值即可。

提示

不建議您將值的副本儲存在 context 中,然後在最後處理它們,因為這會導致 SQLite 使用大量記憶體來處理查詢 — 試想一下,如果一百萬列儲存在記憶體中,每一列都包含一個 32 位元組的字串,您將需要多少記憶體。

提示

您可以使用 SQLite3::createAggregate() 覆寫 SQLite 原生的 SQL 函式。

新增註解

使用者貢獻的註解 2 則註解

boris dot dd at gmail dot com
7 年前
<?php
類別 測試 繼承 SQLite3
{
公開 函式
__construct($檔案)
{
父類別::__construct($檔案);
$this->createAggregate('groupConcat', [$this, '合併步驟'], [$this, '合併最終']);
}
公開 函式
合併步驟(&$上下文, $列ID, $字串, $分隔符號)
{
if (!isset(
$上下文)) {
$上下文 = [
'分隔符號' => $分隔符號,
'資料' => []
];
}
$上下文['資料'][] = $字串;
return
$上下文;
}
公開 函式
合併最終(&$上下文)
{
return
implode($上下文['分隔符號'], $上下文['資料']);
}
}
$SQLite = new 測試('/tmp/test.sqlite');
$SQLite->exec("create table `test` (`id` TEXT, `color` TEXT, `size` TEXT)");
$SQLite->exec("insert into `test` (`id`, `color`, `size`) values ('1', 'red', 'M')");
$SQLite->exec("insert into `test` (`id`, `color`, `size`) values ('1', 'green', 'M')");
$SQLite->exec("insert into `test` (`id`, `color`, `size`) values ('1', 'blue', 'S')");
$結果 = $SQLite->query("select `size`, groupConcat(`color`, ';') as `color` from `test` group by `size`");
while (
$列 = $結果->fetchArray(SQLITE3_ASSOC)) {
print_r($列);
}
/*
陣列
(
[size] => M
[color] => red;green
)
陣列
(
[size] => S
[color] => blue
)
*/
sukmaagungsaputra at gmail dot com
9 年前
缺少範例,對吧?
讓我們試著賦予 SQlite3 類似 MySQL 的功能
- REGEXP 運算子,
- MD5 函式, 以及
- GROUP_CONCAT 聚合函式

$db = new SQLite3($filename);

/* 建立新的 SQLite3 資料庫物件。$filename 為資料庫檔案名稱。 */
$db->createFunction('regexp', function ($a,$b) { return preg_match("/$a/i", $b); });

/* 建立名為 "regexp" 的自訂函數,用於執行正規表達式比對,區分大小寫。$a 為正規表達式,$b 為要比對的字串。 */
$db->createFunction('md5', function ($a) { return md5($a); });

/* 建立名為 "md5" 的自訂函數,用於計算字串的 MD5 雜湊值。$a 為要計算的字串。 */
$db->createAggregate ('group_concat',

/* 建立名為 "group_concat" 的自訂聚合函數。 */
function(&$context, $rownumber, $str) { $context[]=$str; return $context; },

/* 聚合函數的步驟函數,將每一列的 $str 值加入到 $context 陣列中。 */
function(&$context) {return implode(",", (array) $context); });

/* 聚合函數的最終函數,將 $context 陣列中的值用逗號連接成字串。 */

To Top