Мой php скрипт перестает работать, потому что ему не хватает памяти.
Вот мой код:
$files = array_diff(scandir($dir_name), array('..', '.'));
if (!empty($files))
{
foreach ($files as $file)
{
if (pathinfo($file, PATHINFO_EXTENSION) == "csv")
{
$fp = fopen($dir_name.$file, 'r');
while (($line = fgetcsv($fp, 0, $delimiter)) !== FALSE)
insert_update(array_map('addslashes', $line), $connect_id);
fclose($fp);
}
}
mysqli_close($connect_id);
}
Я запускал скрипт 4 раза на одном и том же csv (более 600 тыс. Строк).
И точно таким же сценарием он останавливается в разные моменты …
Номер запроса, выполненного до его остановки: 205 286 // 200 514 // 192 429 // 211 164
(Я усекаю таблицу перед каждой попыткой).
Я всегда использовал одни и те же переменные … как можно увеличить объем используемой памяти?
Это только цикл foreach … если он работает один раз, он должен работать неограниченное количество раз, верно?
Спасибо,
Микаэль.
PS: вот моя функция ‘insert_update’
function insert_update($row, $connect_id)
{
$table_name = "xxxxxxxx";
$maxcol = 42;
$my_request = "INSERT INTO $table_name VALUES ('$row[0]'";
$i = 1;
while ($i < $maxcol)
{
if (isset($row[$i]))
$my_request = $my_request.", '$row[$i]'";
else
$my_request = $my_request.", ''";
$i++;
}
$my_request = $my_request.")";
if (mysqli_query($connect_id, $my_request) == FALSE)
{
echo "<p>$my_request</p>";
exit();
}
}
Ваша функция не содержит статики и не должна ничего оставлять позади. Ваш цикл также не хранит ничего в оперативной памяти. Итак, если вы случайно не обнаружили какие-либо memory_leaks в используемых функциях PHP,
Другой проблемой может быть сборщик мусора. Этот сервис освобождает больше не используемую память. Этот сборщик мусора запускается не после освобождения каждого идентификатора переменной, а в собственное время.
Однако теперь вы можете попытаться заставить сборщик мусора освободить память. (Некоторые люди говорят, что это не повлияет на память, как. Не знаю)
gc_collect_cycles()
Некоторая отладка может также помочь вам определить источник утечки:
memory_get_peak_usage();
Вы также можете попытаться увеличить лимит памяти для этого скрипта. Это не должно быть сделано в общедоступном файле, так как это может быстро занять всю память вашего сервера.
ini_set('memory_limit', '1024M');
Другой вариант может состоять в том, чтобы попробовать разные способы доступа к файлам и подключения к базе данных в зависимости от того, что вам доступно.
Если ничего не помогает, создайте какую-то итерацию. Обработайте 10 файлов, затем перенаправьте на ваш скрипт с параметром смещения, чтобы начать с того места, где вы остановились в прошлый раз. Повторяйте, пока все файлы не будут обработаны.
Других решений пока нет …