PHP ajax isteğine yanıt sonra işleme devam etmek için nasıl?

4 Cevap php

Bazı işlemler zaman aşımına ajax isteği yol açan, çok fazla zaman alır.

Bunu nasıl operasyon devam sonra, ilk isteğine yanıt bitirmek mi?

4 Cevap

Bir arka plan işlemi spawn ve kullanıcı bazı gizli URL yoluyla daha sonra kontrol edebilirsiniz böylece arka plan işlemi id döndürülür.

Sıralama başarmak için çalışıyoruz bağlıdır.

Özet bilgi gerçekten - Benim durumumda, ben tarayıcıya geri gönderilen verilerin sadece asgari bir miktarı ile, sunucu tarafında işleme bir demet yapmak gerekiyordu.

Ben bir mesaj gönderen oluşturmak için çalışıyordu - 250 kişiye bir e-posta gönderir, ama belki daha çok (sistemi ile kaç kayıtlı bağlıdır).

PHP posta işleyicisi hızlı, ancak yeterince büyük sayılar için, hızlı değil, bu nedenle zaman aşımına bağlanmıştır. Etrafında almak için, i sunucu / PHP tarafında zaman aşımı gecikme ve tüm veriler özetlenmiştir ve görüntülenen kadar asılı tarayıcı tutmak için gerekli.

Benim çözüm - bir teaser.

aslında, ben kullanıcıya işleme başladı, sayfa altbilgi görüntülenen, 2 DIV kutuları (mevcut durumu bilgi için bir nihai özet bilgi için ikinci) yarattı, (bu çok e-posta göndermek için çalışırken), ve bazı ilk istatistikleri belirten bir mesaj verdi Bittiğinde, özet bilgi güncellenir. şöyle gidiyor:

Işlemek için gidiyoruz veri toplamaya başlayın, ve bazı özet bilgi almak. Benim durumumda, ben, e-posta adreslerinin listesini çıkardı bunları valide ve onları saydı.

: O "teşebbüs" bilgi ekranı

echo "Message contents:";
echo "<blockquote>$msgsubject<p>$msgbody</blockquote><p>&nbsp;</p>";
echo "Attempting <strong>" . $num_rows . "</strong> email addresses.";

Şimdi durumu / nihai bilgi için bazı DIV'leri oluşturun:

<div id=content name=content>
<div id=progress name=progress style='border: black 1px solid; width: ".$boxwidth."px; height: 20px;'></div>
<br>
</div>

$ BoxWidth Eğer ilerleme çubuğu olmak istiyorum genişliği olduğu (daha sonra açıklanacaktır)

Onlar aslında boş olduğunu fark - biz bunları daha sonra dolduracağız.

Son olarak, (benim durumumda ben sadece uygun dosyayı "dahil") sayfa altbilgi göstererek sayfanın kalanını doldurun.

Şimdi, bütün bu sunucuda hala (biz henüz bitti söylendi değil çünkü), bu yüzden o itti olsun ve neden izin veya tarayıcı (PHP tamponlama ise) / ya sayfa tampon dışarı asılı ya da "görmezden" ve yukarıdan "floş" kullanılarak görüntülenir:

ignore_user_abort(true); 
flush();

Tarayıcı şeyler göstermek başlıyor Şimdi, biz kullanıcı görmek için bir şey vermek gerekir, bu yüzden burada kandırmaca - biz iç DIV görüntülemek olacak bir durum çubuğu ve dış DIV için son bir mesaj oluşturmak olacak .

Yani, veri aracılığıyla döngü gibi, periyodik çıktı şu, (senin kadar anlamaya "ne sıklıkla" bırakacağım):

set_time_limit (3);
...
(process your data here)
...
<script>document.getElementById('progress').innerHTML  += "<img src='images/progress_red.gif' width: $width height=20 border=0>"</script>
flush();

Bu aslında bir kırmızı çubuk ekran boyunca hareket görünür kılarak, birbirlerinin yanında küçük 4x20 progress_red görüntüleri yığını olacaktır. Benim durumumda, ben bu şu anda işlemek için toplam sayısı üzerinden işlem ne sayı yüzdesi dayalı 100 kez yaptım. Eğer komut PHP zaman sınırı duvar çalıştırmak olmayacak biliyorum ki "set_time_limit", mevcut sınırı 3 saniye katacak. Gerektiği gibi uygulama için 3 saniye ayarlayın.

sayfa teknik olarak "tam" olsa bile, javascript kodu DIV html güncelleyecektir ve ilerleme çubuğu "hareket" olur.

Tüm bittiğinde, ben o aslında işlendi kaç öğe rapor ve dış DIV html ve sayfaya eklemek tamamlandı:

<script>document.getElementById('content').innerHTML  += "Message was sent to $sentcnt people."</script>

Tüm bu nitelikleri (sayfa syntactially sonu) bir araya geldi vardı çünkü tarayıcı mutlu, kullanıcı hakkı sonuna kadar somethign oluyor görür ve sunucu

Ben bunu yardımcı olabilir, ancak durumda, Javascript yoluyla yapılıyor hiçbir fantezi CSS şeyler varsa JavaScript kullanmak için değil eğilimindedir, bu nedenle tarayıcı sitede ve düşük havai Neler olup bittiğini görmek için oldukça basit ve kolaydır. Ve bu oldukça sorunsuz çalışır.

Ben bu mükemmel iddia etmiyorum, ama bir basit, düşük maliyetli çözüm için, bu cronjobs, ekstra kuyruk mekanizmaları ya da ikincil süreçleri oluşturmak zorunda kalmadan benim için çalışıyor.

Hemen tarayıcıya gönderilen tepki var flush() çağrıyı gerekir.

ignore_user_abort directive, and ignore_user_abort fonksiyonu aradığınızı muhtemelen: bu tarayıcıya yanıtı göndermek için izin, ve, bundan sonra, hala bazı hesaplamalar çalıştırmak gerekir sunucu.

This article about it might interest you : How to Use ignore_user_abort() to Do Processing Out of Band ; quoting :
EDIT 2010-03-22 : removed the link (was pointing to http:// ! waynepan.com/2007/10/11/ ! how-to-use-ignore_user_abort-to-do-process-out-of-band/ -- remove the spaces and ! if you want to try ), after seeing the comment of @Joel.

Basically, when you use ignore_user_abort(true) in your php script, the script will continue running even if the user pressed the esc or stop on his browser. How do you use this?
One use would be to return content to the user and allow the connection to be closed while processing things that don’t require user interaction.

The following example sends out $response to the user, closing the connection (making the browser’s spinner/loading bar stop), and then executes do_function_that_takes_five_mins();

Ve verilen örnek:

ignore_user_abort(true);
header("Connection: close");
header("Content-Length: " . mb_strlen($response));
echo $response;
flush();
do_function_that_takes_five_mins();

(There's more I didn't copy-paste)


Note that your PHP script still has to fit in the max_execution_time and memory_limit constraints -- which means you shouldn't use this for manipulations that take too much time.

Eğer aynı anda yapmak onlarca sayfa olması gerektiği anlamına gelir - Bu aynı zamanda bir Apache süreci kullanacağız.

Yine, kullanım deneyimini geliştirmek için güzel bir hile, sanırım ;-)