При долгом выполнении скрипта отваливается броузер.

D.K.M.

Новичок
При долгом выполнении скрипта отваливается броузер.

Выполняется импорт продукции их xml файла.
При этом скрипт ничего невыводит на экран пользователю, а в конце скрипта выполняется переадресация Header('url');

При этом через некоторое время броузер просто отваливается и показет надпись: Невозможно отобразить страницу. Выполнение скрипта тоже прерывается (Из 1300 записей за это время он успел импортнуть ~750).

Теперь интересное: вставил в цикл импорта строку
PHP:
echo("импорт - ".$i."\n");
flush();
$i - соответственно номер позиции. После этого, все 1300 позиций импортнулись на ура, но, естественно, несработала переадресация Header('url');

Вопросов как всегда два: кто виноват? и что делать?
 

D.K.M.

Новичок
Очень прикольно.
это ж надо сколько проблем я себе наживу с этими редиректами и записями в сессию!

Лучше я буду что-то пользователю бросать на экран, чем перебрасывать его со страницы на страницу....

Может есть какой другой способ?

Итересно также: кто рвет конект? Броузер или сервер хостеров?
 

Romantik

TeaM PHPClub
=)
перечисли мне хоть одну проблему если ты 1300 позиций сделаешь за 2 прохода (750 то умещаются)

В тему:
Она: - Мужчина, вы трудности любите?
Он: - Это мой стиль жизни!
Она: - А если я с вами сексом займусь?
Он: - Только в гамаке и стоя!
 

tony2001

TeaM PHPClub
>Вопросов как всегда два: кто виноват? и что делать?
не делать интерактивно то, что должно делаться в бэкграунде.
для этого есть крон и гугль.
 

D.K.M.

Новичок
смотри:
скрипт уже написан и работает.
в нем: парсинг xml, перекодировка и импорт в базу - все работает.
теперь то что придеся сделать:
1. отделить последнюю часть.
2. сохранить в сессию всю эту кучу товара
3. редирект на второй скрипт который делает импорт продукци в базу
4. подсчитывать количство продукции и каждые 500 позиций перекидывать человека на этот же скрипт с другой начальной позицией.
5. Ну и незабыть выйти и переадрисовать того же человека на страницу выполнения.

Так же там ведутся всякие логи по продукции тоже незабыть это все нормально открывать/закрывать.
 

Romantik

TeaM PHPClub
D.K.M.
Ничего сложного, если ввести флаг окончания процесса, когда идет последний цикл.
 

D.K.M.

Новичок
Крон это хорошо, но импорт должен выполнять пользователь тогда когда ему это необходимо.
И по времени не так уж долго получается: на локальной машине 2 минуты, у хостеров около 3х минут (это с выводом на экран).

Все же должен быть выход.
На других хостингах работает! И импортирует до 3000 позиций.

ПС: про секс в гамаке и стоя - и кто получит удовольствие?
 

ksnk

прохожий
D.K.M.
2 минуты молчания - не дело! Юзер должен видеть, что его не кинули и не подвесили :) Так что выводить информацию о ходе выполнения задачи следует!
А вот в конце можно вывести что-то типа
<script>document.location="site"</script>
<a href='site'> Жми сюда, если JS отключен!</a>
и будет практически то, что надо!
 

WP

^_^
У меня вообще индексация в движке (паучок ходит по сайту и собирает инфу), она может выполняться хоть час. Когда пользователь жмет кнопку "Запуск", броузер создает объект картинки (new Image()), устанавливает для нее URL до скрипта, который в свою очередь пишет в БД что он запустилсо и работает (время последней записи в БД и флаг), в это время броузер перезгружает страницу, берет данные из БД и показывает что "Идет индексация...", и перегружает страницу каждые 10 секунд. А когда паук приползает обратно, он пишет в БД что всё ок, и при очередном релоде пишет что всё готово. В скрипте паука set_time_limit(0); и ignore_user_abort(1);
 

Stierus

Новичок
Полностью согласен с ksnk ... выводить информацию о ходе работы нужно ... просто в конце добавляй javascript, перебрасывающий куда нужно по onload
 

D.K.M.

Новичок
сейчас так и сделал - работает.
но решение мне ненравится :-(
 

ksnk

прохожий
вот еще вариант, это если без Java script'а и под Винду... Под *nix нужно смотреть комментарии к [m]exec[/m] и писать как там написано
test.php
PHP:
<?php
  if (isset($_GET['run'])) {
    pclose(popen("start /b C:\\WebServers\\usr\\local\\php\\php.exe -f d:\\php\\test\\verylong.php", 'r'));
    header('location: test.php');
    exit ;
  }
  if (isset($_GET['status'])) {
?>
   <head>
   <meta http-equiv=Refresh Content='10'>
   <meta http-equiv="content-type" content="text/html; charset=windows-1251">
   </head>
   <body><pre><?=file_get_contents('status.txt')?></pre></body>
<?
   exit ;
  };
?>
<head>
<title>status</title>
<meta http-equiv=Refresh Content='10'>
<meta http-equiv="content-type" content="text/html; charset=windows-1251">
</head>
<form name="form1" method="post" action="?run=1">
  <input name="Запуск" type="submit"  value="Submit">
</form>
<p><iframe src="?status=1" height="100" width="100%"></iframe></p>
verylong.php

PHP:
<?php
  function status($s)
  {
     $handle=fopen('status.txt',"w");
	 if ($handle) {
     	if (flock($handle, LOCK_EX)) { // do an exclusive lock
           fwrite($handle,$s);
           flock($handle, LOCK_UN); // release the lock
        }
    	fclose($handle);
   	 }
  }
  status('starting...');
  set_time_limit(0);
  ignore_user_abort(true);
  for ($i=1;$i<10;$i++) {
    sleep(10); status ('running... stage '.$i);
  }
  status('complete...');
?>
 

D.K.M.

Новичок
Вообщем все решилось не так как я хотел, но все же.
Скрипт только выкладывает файл на хост и ставит метку что файл на хосте.
Импортирующий скрипт закинул в крон. Он проверяет метку начала и если она стоит то выполняет импорт. В конце ставит метку успеха импорта (или неудачи).

А броузер ходит каждые 15 секунд на сервер за результатом, до тех пор пока не получит конечный результат.

На вопрос кто рвет конект, я нашел ответ в логах Апача:
Апач неполучая от скрипта никакого вывода просто прерывает процес, считая его зависшим.
 
Сверху