Работа с файлами в PHP. Отвал скрипта на Apache.

zarus

Хитрожопый макак
Работа с файлами в PHP. Отвал скрипта на Apache.

PHP:
    $str = '';
    $buf = '';
    $file = fopen($src_f,'rb');
    while (!feof($file)) {
      $str_read = fread($file,10485760);
      $str .= str_replace(array("\t","\r\n"),array(";","|"),trim($str_read));
      $tbl = explode('</table>',$str);
      $str = array_pop($tbl);
      if (is_array($tbl)) {
        foreach ($tbl as $var) {
          if (preg_match_all('/<td>([0-9]+?)=((?:.(?!<td>))*.)/si',strval($var),$m,PREG_SET_ORDER)) {
            $f = array_fill(0,$max,'');
            foreach ($m as $v) {
              $ind = intval($v[1]);
              if ($ind > $max) {
                continue;
              }
              $f[$ind] = strip_tags($v[2]);
            }
            $buf .= implode("\t",$f)."\r\n";
            $ct++;
            if ($ct%1000 == 0) {
              echo '<script>document.control.cnt.value = '.$ct.';</script>';
            }
          }
        }
      }
      echo '<script>document.control.cnt.value = '.$ct.';</script>';
      if (strlen($buf) > 10485760) {
        fwrite($fo,$buf);
        $buf = '';
      }
    }
На одном из файлов этот скрипт "отваливается", а в браузер возвращается ошибка "Сервер не найден". Причем никаких ошибок в логах Апача и ПХП не наблюдается. В чем может быть беда?
Скрипт рабочий - на файле размером 250 Мб он "нормально" работает. А вот на другом файле - размером 500+ Мб "умирает".
Помогите! Есть ли другие варианты заставить этот скрипт работать? И приму полезные ссылки почитать по теме (ПОИСК не помог) и варианты ускорить работу скрипта.
У меня подозрения, что проблема в настройках Апача - но в этом деле я "ламер".

з.ы. Замечания типа "У тебя ошибка в коде ДНК" можете оставить себе :)
 

tony2001

TeaM PHPClub
На одном из файлов этот скрипт "отваливается", а в браузер возвращается ошибка "Сервер не найден". Причем никаких ошибок в логах Апача и ПХП не наблюдается. В чем может быть беда?
браузер просто устаёт ждать контент и отваливается.
 

zarus

Хитрожопый макак
Автор оригинала: tony2001
обоснуй.
Ставим размер считывания 1024 байта, делаем в цикле вывод в браузер на каждом шаге цикла, и скрипт все равно отваливается. Более того, я же написал, что скрипт нормально работает на "небольшом" файле.
 

tony2001

TeaM PHPClub
вывод в цикле ничего не значит до тех пор, пока там нет [m]flush[/m]() - весь вывод накапливается в буфере, а потом выдается клиенту одним махом.

>скрипт все равно отваливается
не скрипт, а браузер.

>Более того, я же написал, что скрипт нормально работает на "небольшом" файле.
браузер ждёт N секунд и отваливается.
если меньше N секунд - он дожидается ответа.

Можешь считать, что я вернул тебе твою "чушь".
 

SiMM

Новичок
> Ставим размер считывания 1024 байта, делаем в цикле вывод в браузер на каждом шаге цикла, и скрипт все равно отваливается.
Ну и что. [m]flush[/m]

> Более того, я же написал, что скрипт нормально работает на "небольшом" файле.
Вот именно.
 

zarus

Хитрожопый макак
> Ставим размер считывания 1024 байта, делаем в цикле вывод в браузер на каждом шаге цикла, и скрипт все равно отваливается.
Ну и что. flush
> Более того, я же написал, что скрипт нормально работает на "небольшом" файле.
Вот именно.
Вот именно, что Ваши конкретные советы мне не помогают.
PHP:
  echo '<form name="control">Обработано записей: '.'<input name="cnt" value="0" size="8" /></form>';
  $meth = isset($_POST['RW']) ? 'a' : 'w';
  $src_f = $_POST['src'];
  $new_f = preg_replace('/^(.*)(\..*)$/','\1_converted\2',$src_f);
  $max = !empty($_POST['CN']) ? intval($_POST['CN'])+1 : 10;
  if (file_exists($src_f)) {
    for ($c=0;$c<$max;$c++) {
      $f[$c] = $c;
    }
    $fo = fopen($new_f,$meth);
    fwrite($fo,implode("\t",$f)."\r\n");
    $ct  = 0;
    $str = '';
    $buf = '';
    $file = fopen($src_f,'r');
    while (!feof($file)) {
      $str .= fgets($file);
      $tbl = preg_split('/<\/table>(?:.*?)<table>/si',$str,-1);
      $str = array_pop($tbl);
      if ($str === null) {
        $str = '';
      }
      foreach ($tbl as $var) {
        if (preg_match_all('/<td>([0-9]+?)=((?:.(?!<td>))*.)/si',$var,$m,PREG_SET_ORDER)) {
          $f = array_fill(0,$max,'');
          foreach ($m as $v) {
            $ind = intval($v[1]);
            if ($ind <= $max) {
              $f[$ind] = str_replace(array("\t","\r\n"),array(";","|"),trim(strip_tags($v[2])));
            }
          }
          $buf .= implode("\t",$f)."\r\n";
          $ct++;
          echo '<script>document.control.cnt.value = '.$ct.';</script>';
          flush();
        }
      }
      fwrite($fo,$buf);
      $buf = '';
    }
    if (strlen($buf) > 0) {
      fwrite($fo,$buf);
      $buf = '';
    }
    echo '<script>document.control.cnt.value = '.$ct.';</script>';
    flush();
    fclose($fo);
    fclose($file);
  }
Браузер отваливается. Апач убивает процесс - и непонятно, кто из них первый.

К сожалению, там ничего нет, т.е. абсолютно пусто. Скрипт просто отваливается :(

Вопрос остается открытым...
 

Steamroller

Новичок
А если когда этот скрипт запускаешь - в консоли top'ом на Апач смотришь - сколько он памяти жрет в процессе работы?
 

SiMM

Новичок
> Вот именно, что Ваши конкретные советы мне не помогают.
Вот именно что чем больше файл, тем больше время отработки скрипта - факт, думаю, очевидный, и спорить с ним абсолютно бессмысленно и глупо.

httpd.conf -> Timeout для начала + хостер наверно может процесс прибивать.
 

si

Administrator
Steamroller
в главный error.log апача а не в erorrlog от virtualhost
 

zarus

Хитрожопый макак
> Вот именно, что Ваши конкретные советы мне не помогают.
Вот именно что чем больше файл, тем больше время отработки скрипта - факт, думаю, очевидный, и спорить с ним абсолютно бессмысленно и глупо.
Согласен, спорить с Вами бессмысленно и глупо. Поясняю, скрипт умирает через несколько секунд после запуска, а не по стандартному таймауту браузера.
в главный error.log апача а не в erorrlog от virtualhost
И там, и там - ПУСТО. Если бы там хоть какие-то следы были, я бы тут не сидел, а Яндекс мучал.

В общем, закрывайте тему, так как проблема скорее всего не в работе с файлами, а с кривой версией апача. Спасибо за помощь.

-~{}~ 15.11.05 11:29:

Разобрался с проблемой.
preg_match_all получал очень длинную строку (>255 символов) в один из подэлементов массива результатов, и убивал скрипт.
Пришлось делать preg_match & preg_replace в цикле. И быстродействие скрипта выросло на порядок :|
 
Сверху