В настоящее время я зацикливаюсь на создании карты 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
Я проверил решение, написанное здесь: Как предотвратить SQLITE SQLSTATE[HY000] [14]?, но эхо-сообщение появляется только в первый раз цикла, поэтому я предполагаю, что соединение PDO не закрыто.
Я не нашел другой документации, относящейся к этому коду ошибки.
Что тут может пойти не так?
Я попытался переместить команды подготовки и привязки в состояние следующим образом. Исключение не возникает, но сохраняется только первая плитка (или каждая плитка сохраняется поверх первой, не уверен):
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();
А здесь после возбуждения исключения:
Кроме того, когда возникает исключение, я делаю var_dump своих $pdo_mbtiles, и вот результат (точно такой же, как если бы я сделал это с успехом):
object(PDO)#116 (0) {
}
Изменить. Пытаясь решить эту проблему, я упростил код для создания файла MBTiles. Пока безуспешно, но вот пример, если кто-то хочет воспроизвести проблему. Вы можете скачать его с https://www.dropbox.com/s/33vqamc9tn4c3ux/sample_PHP_MBTiles_generation_bug.zip?dl=0
setAttributes()
внутрьif
, поскольку их нужно запускать только один раз при подключении, а не каждый раз по циклу. Или добавьте их в массив атрибутов, который вы уже используете в соединении. - person RiggsFolly   schedule 11.09.2015closeCursor()
. - person JimmyB   schedule 11.09.2015