我目前正在循环创建一个MBTiles地图,每次都向数据库中添加信息。
下面是我如何配置连接并在循环期间执行操作的:
if ($pdo_mbtiles == null) {
echo "Opening new database connection".PHP_EOL;
$pdo_mbtiles = new PDO('sqlite:'.$filename,
'',
'',
array(
PDO::ATTR_PERSISTENT => true
)
);
$pdo_mbtiles->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
$pdo_mbtiles->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
$q = $pdo_mbtiles->prepare("INSERT INTO tiles (zoom_level, tile_column, tile_row,tile_data) VALUES (:zoom_level, :tile_column, :tile_rowTMS, :tile_data)");
$q->bindParam(':zoom_level', $zoom_level);
$q->bindParam(':tile_column', $tile_column);
$q->bindParam(':tile_rowTMS', $tile_rowTMS);
$q->bindParam(':tile_data', $tile_data, PDO::PARAM_LOB);
$q->execute();
在1018次循环之后(无论我尝试多少次,这个数字都不会改变),我得到了以下错误消息:
SQLSTATE[HY000]: General error: 14 unable to open database file
我检查了写在这里的解决方案:
How to prevent SQLITE SQLSTATE[HY000] [14]?
但是回显消息只在循环的第一次出现,所以我假设PDO连接没有关闭。
我没有找到与此错误代码相关的其他文档。
这里可能会出什么问题?
我尝试在如下条件下移动prepare和bind命令。不会引发异常,但只保存第一个磁贴(或者每个磁贴都保存在第一个磁上,不确定):
if ($pdo_mbtiles == null) {
echo "Opening new database connection".PHP_EOL;
$pdo_mbtiles = new PDO('sqlite:'.$filename,
'',
'',
array(
PDO::ATTR_PERSISTENT => true
)
);
$pdo_mbtiles->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
$pdo_mbtiles->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
if ($q == null) {
$q = $pdo_mbtiles->prepare("INSERT INTO tiles (zoom_level, tile_column, tile_row,tile_data) VALUES (:zoom_level, :tile_column, :tile_rowTMS, :tile_data)");
$q->bindParam(':zoom_level', $zoom_level);
$q->bindParam(':tile_column', $tile_column);
$q->bindParam(':tile_rowTMS', $tile_rowTMS);
$q->bindParam(':tile_data', $tile_data, PDO::PARAM_LOB);
}
$q->execute();
以下是生成过程中的文件:
在引发异常之后:
此外,当引发异常时,我对$pdo_mbtiles进行var_dump,结果如下(与成功执行时完全相同):
object(PDO)#116 (0) {
}
编辑:
仍在尝试解决这个问题,我简化了代码以创建MBTiles文件。还没有成功,但如果有人想复制这个问题,这里有一个示例。您可以从
https://www.dropbox.com/s/33vqamc9tn4c3ux/sample_PHP_MBTiles_generation_bug.zip?dl=0