Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Вывод результатов по мере выполнения PHP... Как: ajax, qjuery, flush?

63K
28 ноября 2010 года
Deliaz
15 / / 27.11.2010
Доброго времени суток!

В свободное время учусь web-программированию методом "реализации пришедших_в_голову идей"

И вот у меня задача: есть php скрипт, в стиле
Код:
...
ob_start();
for($i=1;$i<=15;$i++)
{
    $T_SOCK=@fsockopen($T_HOST,$PORTS[$i],$err1,$err2,3);
    if($T_SOCK)
    {
        echo "<br>Открыт:",$PORTS[$i];
        fclose($T_SOCK);
    }
    else {echo "<br>Закрыт:",$PORTS[$i];}
    flush(); ob_flush();
}
ob_end();
}...


И я захотел чтобы результат выводился постепенно, по мере проверки конкретного порта.
Гугл рассказал мне про flush(), ob_flush() и прочее подобное. Но тут проблемы: При тестировании, в некоторых браузерах (chrome, IE) оказалось что для начала буфер требуется забить миниму 256 символами. :(
Эксперимент с php.ini (output_buffering и implicit_flush) ничего не дал. [COLOR="DimGray"](Возможно браузеры игнорируют эти настройки? Тестировал на последнем денвере..)[/COLOR]

Ладно, думаю, черт с ним - сначала выпустил ~300 пробелов. Везде заработало (кроме сафари,[COLOR="DimGray"] вроде как должна быть кроссбраузерность?))[/COLOR] ), но результат выводится рывками, то по 1 строке? нормально, то сразу охапками по 2-3.
Переставлял flush'ы и так и сяк. Много уже попробовал.
Думается можно решить по другому задачу.

Прочитал про ajax, jquery. Попытка что-то найти в сети привела к тоннам мануалов, документаций, по безпредметной теме, хотя я искал всего-лишь пример или решение того, как сделать "порезультатный" вывод.

В общем ищу советов, идей, подсказок, с учетом моих новичковых знаний

Спасибо
274
28 ноября 2010 года
Lone Wolf
1.3K / / 26.11.2006
Ну поповоду Ajax, прийдется переделать скрипт.
пхп-скрипт будет тестировать только один порт, какой ему укажется в запросе.
А вот уже ЖС, будет перебирать порты и слать запросы для чека каждого.
Имхо это не ефетивно.

Также можешь покопать в сторону Comet
63K
28 ноября 2010 года
Deliaz
15 / / 27.11.2010
Буду комет смотреть, спасибо.

А по-поводу ЖС, я так понял можно будет достичь многопоточности?
274
28 ноября 2010 года
Lone Wolf
1.3K / / 26.11.2006
Ну аджакс асинхронный, по сему можно сказать да.. "многопоточность" будет.

Вот накидал пример на скорую руку. Использую Prototype, а не jquery, хотя мождно и чистом ЖС сделать не приниципиально.

Гланвое понять идею, а уже пото модифицировать под свои требвоания.

[highlight=javascript]
for(i=0; i<100; i++)
{
new Ajax.Request('/getPortStatus?port='+i,{
method:get,
onSuccess: function(transport) { $('port-'+i).update(transport.responseText); }
})
}
[/highlight]

[highlight=php]
$i=$_GET['port'];
$T_SOCK=@fsockopen($T_HOST,$PORTS[$i],$err1,$err2,3);
if($T_SOCK)
{
echo "<br>Открыт:",$PORTS[$i];
fclose($T_SOCK);
}
else {echo "<br>Закрыт:",$PORTS[$i];}
[/highlight]

[COLOR="Silver"]P.S. Сам пример может и не совсем рабочий, накидывал сразу на форум.. мож де и ошибся в чем..[/COLOR]
63K
28 ноября 2010 года
Deliaz
15 / / 27.11.2010
Спасибо. Мне понимание идеи и основы кода как раз и нужны.

Принцип, на котором вообще, как я понимаю, может работать такая реализация:
  1. В теле страницы есть некий js код
  2. Он отправляет по одному проверочному запросу php скрипту
  3. При этом, js код, не перезагружая страницу, тут же возвращает результат

Суть верна?

Сделать по подобному хочу

Ещё такой вопрос, если я js циклом без задержек скармливаю скрипту массив, следовательно это всё сразу и обрабатывается. Может нужна пауза?

И возможна ли защита от подделки get запроса? Я о том, что js лежит в теле страницы, передавать ею порт опасно - не сложно написать парсер, отправляющий свои любые порты. Может в php сразу поместить массив портов, в js будет просто передавать индекс.. Либо контролировать на уровне скрипта php поступаемые порты
[COLOR="DimGray"](Это наверно уже просто размышления вслух)[/COLOR]
274
28 ноября 2010 года
Lone Wolf
1.3K / / 26.11.2006
Цитата: Deliaz
Спасибо. Мне понимание идеи и основы кода как раз и нужны.

Принцип, на котором вообще, как я понимаю, может работать такая реализация:
  1. В теле страницы есть некий js код
  2. Он отправляет по одному проверочному запросу php скрипту
  3. При этом, js код, не перезагружая страницу, тут же возвращает результат

Суть верна?


Абсолютно

Цитата: Deliaz

Сделать по подобному хочу



интерестно.. а в ИЕ оно нормально работает? У мну ИЕ нету, проверить не могу..

Цитата: Deliaz

Ещё такой вопрос, если я js циклом без задержек скармливаю скрипту массив, следовательно это всё сразу и обрабатывается. Может нужна пауза?



Думаю да. задержка будет полезной. Но это все зависит от нагрузок что сервак выдерживает, кол-во одновременных юзеров на сайте...
Как вариант разбивать диапазоны на группы, и делать след запрос только после получения ответа.

т.е. в моем примере, следуйщий порт запрашивать уже в методе onSuccess


Цитата: Deliaz

И возможна ли защита от подделки get запроса? Я о том, что js лежит в теле страницы, передавать ею порт опасно - не сложно написать парсер, отправляющий свои любые порты. Может в php сразу поместить массив портов, в js будет просто передавать индекс.. Либо контролировать на уровне скрипта php поступаемые порты
[COLOR="DimGray"](Это наверно уже просто размышления вслух)[/COLOR]



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

369
28 ноября 2010 года
Kesano
451 / / 09.10.2007
Имхо, предлагать человеку так с ходу Комет - это зло...
На ЖС и прототайпах - можно конечно, но как по мне, это увеличит время выполнения...

Попробуйте flush();

 
Код:
for($i=0; $i<15; $i++) {
    echo $i.'<br/>';
    flush();
    sleep(1);
}

У меня сей код выводит информацию сразу после эхи, а не пока пройдет 15 циклов... Может и вам пригодится.. буферизирование, мне кажется, здесь ни к чему...

И еще... проверьте у себя max_execution_time кажется так параметр называется.... обычно максимальное время выполнения 30 секунд... Вряд ли этого хватит на все порты... так что измените это значение в большую сторону... если можете...

Извините, если неправильно понял задячу.
upd.1
Вижу, flush вы попробовали... только не знаю, зачем ob_start() и т.д...
upd.2
Проверил в хроме.. действительно лажа... :( А в ФФ нормально... тогда наверное, аяксом...
upd.3
Попробуйте как здесь: _http://mr-faster.com/long-time-job.html
Может изменение буфера в 0 байт поможет...
5
28 ноября 2010 года
hardcase
4.5K / / 09.08.2005
Плохая это идея - выполнять длительные операции в обработчике HTTP-запроса:
1) клиент может отвалиться по таймауту подключения
2) система может прибить длительный запрос
3) можно уложить DDoS-ом Web-сервер.

Я бы для длительных задач изготавливал отдельный демон. Постановка задачи демону - запись в специальную таблицу в БД. В этой же таблице можно организовать хранение прогресса выполнения задачи а также её состояение, в случае если работу демона решили прервать, а какую-то задачу он не выполнил.
63K
28 ноября 2010 года
Deliaz
15 / / 27.11.2010
[QUOTE="Lone Wolf"]интерестно.. а в ИЕ оно нормально работает? У мну ИЕ нету, проверить не могу..[/QUOTE]
Да, даже в ie работает.

[QUOTE="Kesano"]Попробуйте flush();[/QUOTE]
Это был бы самый короткий и верный способ.
Но вот Ваш пример

А вот пример со сканером
Его код:
Код:
<?php
$T_HOST = $_SERVER['REMOTE_ADDR'];
echo $T_HOST;
$PORTS=array(1=>21,2=>23,3=>25,4=>53,5=>80,6=>110,7=>139,8=>8000,
9=>8080,10=>3128,11=>3389,12=>6588,13=>1080,14=>5900,15=>8888);
for($i=1;$i<=15;$i++)
{
    $T_SOCK=@fsockopen($T_HOST,$PORTS[$i],$err1,$err2,3);
    if($T_SOCK)
    {
        echo "<br>Открыт:",$PORTS[$i];
        fclose($T_SOCK);
    }
    else {echo "<br>Закрыт:",$PORTS[$i];}
    flush();
    sleep(1);
}
?>

У меня (Chrome) нормально не работает ни первый, ни второй.
Я понимаю это потому, что буфер для вывода не накопил минимального кол-ва информации для выводы.
Если дома, на денвере я могу поэкспериментировать с конфигами, то к сожалению у хостера не могу.[COLOR="Silver"] Мне предоставлен только ftp доступ[/COLOR]

Поэтому видимо, от простой идеи с flush стоит отказать теперь уже?

Kesano, пока писал сообщение, вы уже обновили своё)

hardcase, роль Бд может выполнить файл, а демон следит за его изменением. Или я не так всё понял?
63K
28 ноября 2010 года
Deliaz
15 / / 27.11.2010
Цитата: hardcase
Плохая это идея - выполнять длительные операции в обработчике HTTP-запроса:
1) клиент может отвалиться по таймауту подключения


А если указаны четки временные рамки на каждую операцию, и они около 3-4 сек.
Т.е. это время на каждую проверку порта, слишком большой тайм-аут вроде не должен быть

5
28 ноября 2010 года
hardcase
4.5K / / 09.08.2005
Цитата: Deliaz
А если указаны четки временные рамки на каждую операцию, и они около 3-4 сек.


Все зависит от интенсивности запросов и сложности операций, которые там выполняются.

5
28 ноября 2010 года
hardcase
4.5K / / 09.08.2005
Цитата: Deliaz

hardcase, роль Бд может выполнить файл, а демон следит за его изменением. Или я не так всё понял?


А как вы себе представляете разруливание параллельного доступа на запись? ;) Файл может выступать в роли БД только в режиме чтения.

63K
28 ноября 2010 года
Deliaz
15 / / 27.11.2010
Цитата: hardcase
А как вы себе представляете разруливание параллельного доступа на запись? ;) Файл может выступать в роли БД только в режиме чтения.


Да, как-то не подумал. :)

Пока, честно говоря, на основе моего опыта я могу попробовать через прототайп. Остальное понятно в теории, но не в прямой реализации

15
29 ноября 2010 года
shaelf
2.7K / / 04.05.2005
Оффтопная идея :)) Сейчас занимаюсь кодингом на AS3... А что, если выкинуть всякие кометы и прочую херню и реализовать всё это на флеше... Да, да, именно на флеше. Сделать его в качестве прокси. Сам по себе он отлично работает с сокетами и через ExternalInterface мог бы замечательно общаться с js...
5
29 ноября 2010 года
hardcase
4.5K / / 09.08.2005
Цитата: shaelf
А что, если выкинуть всякие кометы и прочую херню и реализовать всё это на флеше...

С таким же успехом можно и на Сервелате сделать. ;)

63K
29 ноября 2010 года
Deliaz
15 / / 27.11.2010
Всем Спасибо за помощь и консультацию.
В ближайшее время попробую сделать на js (prototype, jquery).
[COLOR="Gray"]Если будут вопросы, Я апну их в этой темке, Вы не против?)[/COLOR]
274
29 ноября 2010 года
Lone Wolf
1.3K / / 26.11.2006
Конечно, нет. Спрашивай ;)
15
30 ноября 2010 года
shaelf
2.7K / / 04.05.2005
Ммм... Не смотрел сильверлайт, но я имел в виду однопиксельнуя флешку. В принципе по тому же принципе реализовываются межбраузерные куки, а так же куки большого размера (скажем 100мб).
63K
04 декабря 2010 года
Deliaz
15 / / 27.11.2010
Слушайте, вот тут начал пробовать разбираться. Не получается, но не удивительно, кодингом недавно занимаюсь (:
Взял за основу код Lone Wolf, мало пока его понимаю, но сделал так:

Файл index.php
Код:
<html>
<body>
<div id="port-1">...</div>
<div id="port-80">...</div>
<div id="port-139">...</div>
<div id="port-3389">...</div>
<script language="javascript" type="text/javascript">
for(i=0; i<4; i++)
{
   new Ajax.Request('/portcheck.php?ind='+i,{
       method:get,
       onSuccess: function(transport) { $('port-'+i).update(transport.responseText); }
   });
}
</script>
</body>
</html>


Запрос идет сюда. Файл portcheck.php
Код:
<?php
$ports=array(1,80,139,3389);
$i=$_GET['ind'];
$T_SOCK=@fsockopen($T_HOST,$ports[$i],$err1,$err2,3);
    if($T_SOCK)
    {
        echo "<br>Открыт:",$ports[$i];
        fclose($T_SOCK);
    }
    else {echo "<br>Закрыт:",$ports[$i];}
    return $T_SOCK;
?>

Отдельно GET запрос на скрипт идет, и нормально возвращает echo...
Теоретически прикидываю что надо доработать где-то после onSuccess
274
05 декабря 2010 года
Lone Wolf
1.3K / / 26.11.2006
а где prototype подключаешь?
63K
05 декабря 2010 года
Deliaz
15 / / 27.11.2010
Ахах) Просто эпик-ошибка) Даже стыдно...
...
Заработало, когда сделал вот так:
Код:
for(i=0;i<4;i++)
{
  document.write(i);
  new Ajax.Request('/portcheck.php?ind='+i,
  {
    method:'get',
    onSuccess: function(transport){
      var response = transport.responseText || "no response text";
      alert("Success! \n\n" + response);
    },
    onFailure: function(){ alert('Something went wrong...') }
  });
}

...
Осталось поиграться вот с этой ф-ией
 
Код:
$('port-'+i).update(transport.responseText);
63K
05 декабря 2010 года
Deliaz
15 / / 27.11.2010
...
Ну вот, окончательно заработало если делать вот так:
:)
[HTML]<html>
<head>
<script src="prototype.js" type="text/javascript">
</script>
</head>
<body>
<div id="port-0">...</div>
<div id="port-1">...</div>
<div id="port-2">...</div>
<div id="port-3">...</div>
<script language="javascript" type="text/javascript">
for(i=0;i<4;i++)
{
new Ajax.Updater($('port-'+i), '/portcheck.php?ind='+i, { method: 'get' });
}
</script>
</body>
</html>[/HTML]

Только вот тут конечно и мультипоточно, это круто. Но открытые порты обновляются быстрее чем закрытые (т. к. они там-аута ждут)

Думаю с апдейтером очерёдность вывода не выполнить?
63K
29 декабря 2010 года
Deliaz
15 / / 27.11.2010
Снова здравствуйте. Вот разобрался с учебой.
Решил приступить к старой задачи (описанной тут).

Столкнулся с трудностью. Казалось мультипоточность это хорошо.. ан нет ):

prototype скрипт отправляет php запросы подряд, но php обрабатывает их все с разными кол-вом времени (от 0 до 3 секунд). Результат приходит ассинхронно и беспорядком.

Как я могу отправлять запросы по очереди? Как контролировать выполнение и возврат предыдущего?

Вот какие наброски
Код:
function fullchk()
  {
     var i=0;
     while(i<8)
     {
         new Ajax.Request('portcheck.php?ind='+i,
         {
            method:'get',
            onSuccess: function(transport)
            {
               var response = transport.responseText || "Error";
               col_full.insert(response);
               },
             });
            i++;
            }
      }
   
/* и такой вариант */

function fullchk2()
{
    var i=0;
    while(i<8)
    {
    tmp=new Ajax.Updater($('col_full'), 'portcheck.php?ind='+i, {
        method: 'get',
        insertion: 'bottom'
        });
    i++;
    }
}


Мне надо сделать запросы последовательно, только после того, как предыдущий обновил страницу
63K
01 января 2011 года
Deliaz
15 / / 27.11.2010
Вот я нашел пример того, как хочу сделать, но пока я не могу понять как бы реализовать
Пример
81K
29 февраля 2012 года
poldevel
1 / / 29.02.2012
<?php
$ss = str_repeat(" ", 1024); // заполнить начальный буфер вывода! (1кБайт)
echo $ss."<pre/>";

$T_HOST = $_SERVER['REMOTE_ADDR'];
echo $T_HOST;
$PORTS=array(1=>21,2=>23,3=>25,4=>53,5=>80,6=>110,7=>139,8=>8000,
9=>8080,10=>3128,11=>3389,12=>6588,13=>1080,14=>5900,15=>8888);
for($i=1;$i<=15;$i++)
{
$T_SOCK = @fsockopen ($T_HOST,$PORTS[$i],$err1,$err2,3);
if($T_SOCK)
{
echo "\nОткрыт:", $PORTS[$i];
fclose($T_SOCK);
}
else {echo "\nЗакрыт:", $PORTS[$i];}
flush();
usleep(10000);
}
echo "\n--------------";
echo "\nDone";
?>
вот нормально работает во всех браузерах кроме Opera , этот браузер не отдает буфер вывода пока php скрипт не завершит работу
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог