如何在 Mac 上本地安装 SQLite 中的扩展?

How to install locally an extension in SQLite on a Mac?

我对安装扩展一窍不通。我被卡住了,因为我不能在 SQLite 中使用 SQRT。

我在本地机器上使用 Laravel,并且正在处理我的 PHP 单元测试。在一个测试中,我使用了一个带有一些繁重数学函数的查询。

我收到错误:

Caused by
PDOException: SQLSTATE[HY000]: General error: 1 no such function: SQRT

我发现 SQLite 有一个扩展名为:extension-functions.c

我下载了它,但我不确定我是否做对了(显然不是因为它不起作用):

  1. 我下载了它并在我的终端中使用了它

    gcc -fno-common -dynamiclib extension-functions.c -o libsqlitefunctions.dylib
    
  2. 它编译了这个数据:libsqlitefunctions.dylib
  3. 用php --ini if 发现我的php.ini位于/usr/local/etc/php/7.1/php.ini
  4. 现在我查找了 sqlite3 并发现了这条评论;sqlite3.extension_dir =
  5. 我改成了

    sqlite3.extension_dir =/usr/local/etc/php/7.1/extension/libsqlitefunctions.dylib
    
  6. 并创建扩展文件夹并将dylib文件放入其中

  7. 我用 sudo apachectl restart 重启了我的 apache

  8. 并尝试了我的查询,但仍然失败。我做错了什么?

对于未来的读者

要在 Laravel 中使用它,您可以这样称呼它:

$pdo = DB::connection()->getPdo();
$pdo->sqliteCreateFunction('SQRT', 'sqrt', 1);
$pdo->sqliteCreateFunction('ASIN', 'asin', 1);
$pdo->sqliteCreateFunction('SIN', 'sin', 1);
$pdo->sqliteCreateFunction('COS', 'cos', 1);
$pdo->sqliteCreateFunction('POWER', 'pow', 2);
$pdo->sqliteCreateFunction('pi', 'pi', 0);

您似乎想将此与 PDO 一起使用。问题是加载扩展只能直接使用 SQLite3 api,使用 SQLite3::loadExtension 方法。

PDO 驱动程序不允许加载扩展(参见 "Security Considerations" 下的 this wiki entry regarding LoadableExtensions)。

所以你可以直接切换到 SQLite3 api 或者你可以使用 "user defined functions" 和 PDO。例如,如果您需要 SQRT 函数:

$db = new PDO('sqlite:testdb.sqlite', null, null, [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
]);

$db->sqliteCreateFunction('SQRT', 'sqrt', 1);

$stmt = $db->query("SELECT sqrt(25)");
foreach ($stmt as $row) {
    echo $row[0], PHP_EOL; // output: 5.0
}

您的扩展提供的大多数数学函数映射 1:1 到 PHP 函数名称(如 sqrt),因此创建您需要的函数应该很容易。

您似乎将 sqlite3.extension_dir 属性 指向 文件 而不是 目录 。根据 manual for sqlite3extension_dir 属性 是:

[The] Path to the directory where the loadable extensions for SQLite reside.

我认为如果你改变它可能会起作用

sqlite3.extension_dir = /usr/local/etc/php/7.1/extension/libsqlitefunctions.dylib

sqlite3.extension_dir = /usr/local/etc/php/7.1/extension

但是,我会为 SQLite3 扩展创建一个单独的目录,这样它们就不会与 PHP 扩展混合;我这样说是因为您目前似乎正在为 sqlite3.extension_dir 属性 使用 PHP 扩展目录。 (如果你不是,那么请忽略这条注释。)我假设 SQLite3 只是扫描配置目录以查找可加载模块并使用 dlopen 之类的东西加载它们。如果它尝试加载 PHP 扩展,这可能会发生冲突。 (谁知道,它可能会优雅地处理这个问题。)