[ОТРЕДАКТИРОВАНО, ЗДЕСЬ КОРОТКАЯ ВЕРСИЯ]
Циклический просмотр файла и чтение содержимого, а затем запись приводят к сбою функции. Оказалось проблема с памятью. Это три версии, которые я пробовал.
Сначала попробовал это:
$file = new SplFileObject($this->getDirectoryPath() . $this->getFileName(), "a+");
$file->setFlags(SplFileObject::DROP_NEW_LINE | SplFileObject::SKIP_EMPTY);
if ($this->exists()) {
foreach ($file as $line) {
$tempArray = unserialize($line);
if ($tempArray['Key'] == $arrayOfData['Key']) {
foreach ($totalsToBeAdded as $key) {
$arrayOfData[$key] += $tempArray[$key];
}
}
}
}
$tempString = serialize($arrayOfData);
$file->fwrite("$tempString\r\n");
$this->numLines++;
Затем я попробовал это:
$file = new SplFileObject($this->getDirectoryPath() . $this->getFileName(), "a+");
$file->setFlags(SplFileObject::DROP_NEW_LINE | SplFileObject::SKIP_EMPTY);
if ($this->exists()) {
while (!$file->eof()) {
$tempArray = unserialize($file->current());
if ($tempArray['PartNumber'] == $arrayOfData['PartNumber']) {
foreach ($totalsToBeAdded as $key) {
$arrayOfData[$key] += $tempArray[$key];
}
}
$file->next();
}
}
$tempString = serialize($arrayOfData);
$file->fwrite("$tempString\r\n");
$this->numLines++;
И, наконец, я отказался от SplFileObject и просто пошел с обычным fopen и т. д.:
$handle = fopen($this->getDirectoryPath() . $this->getFileName(), "a+");
if ($this->exists()) {
while (false !== ($line = fgets($handle))) {
$tempArray = unserialize(trim($line));
if ($tempArray['Key'] == $arrayOfData['Key']) {
foreach ($totalsToBeAdded as $key) {
$arrayOfData[$key] += $tempArray[$key];
}
}
}
}
$tempString = serialize($arrayOfData);
fwrite($handle, "$tempString\r\n");
fclose($handle);
$this->numLines++;
РЕДАКТИРОВАТЬ ДЛЯ ДОПОЛНИТЕЛЬНОЙ ИНФОРМАЦИИ:
Мне было любопытно, использует ли базовый код PHP массив для итераторов при проходе строки за строкой через файл, что может убить его.
Кроме того, файл начинает создаваться, я могу наблюдать, как он пишет, пока не достигнет 500-600 КБ, а затем умирает.
Окончательный размер файла будет около 10 мб.
Последнее обновление:
Это работает (обратите внимание на отсутствие открытия и чтения файла):
public function writeUnique($arrayOfData, $totalsToBeAdded) {
$tempArray = array();
$handle = fopen($this->fullPath, "a+");
$tempString = serialize($arrayOfData);
fwrite($handle, "$tempString\r\n");
fclose($handle);
$this->numLines++;
}
Пока это ломается (обратите внимание, что ВСЕ, что делается, зацикливается на всем файле, ТОГДА записывается в файл):
public function writeUnique($arrayOfData, $totalsToBeAdded) {
$tempArray = array();
$handle = fopen($this->fullPath, "a+");
if ($this->exists()) {
while (false !== ($line = fgets($handle))) {
}
}
$tempString = serialize($arrayOfData);
fwrite($handle, "$tempString\r\n");
fclose($handle);
$this->numLines++;
}
ОБНОВЛЕНИЕ НОМЕР ТРЕТЬЕ:
Я сейчас проверил это:
public function writeUnique($arrayOfData, $totalsToBeAdded) {
$handle = fopen($this->fullPath, "a+");
if ($this->exists()) {
while (false !== ($line = fgets($handle))) {
}
}
$tempString = serialize($arrayOfData);
// fwrite($handle, "$tempString\r\n"); Commented out the writing.
fclose($handle);
$this->numLines++;
}
Это сработало. Никаких сбоев, ошибок памяти или других ошибок.
Таким образом, похоже, что это либо проблема с итерациями повторного чтения одних и тех же строк большого файла, либо часть функции записи каким-то образом наступает на пятки функции чтения... что, честно говоря, не имеет смысла . Я знаю, что все думали, что это как-то связано с моими массивами. Но я очень сильно убрал ВСЮ свою логику, и я просто пытаюсь читать/писать большой файл.
trime($line)
это опечатка, и вы имели в видуtrim
, или это пользовательская функция, которую вы сделали? Очевидно, что в PHP нет функцииtrime()
- person Anthony Hatzopoulos   schedule 02.11.2012