Apakah ada cara di PHP untuk melakukan panggilan HTTP asinkron? Saya tidak peduli dengan jawabannya, saya hanya ingin melakukan sesuatu seperti file_get_contents()
, tetapi tidak menunggu permintaan selesai sebelum mengeksekusi sisa kode saya. Ini akan sangat berguna untuk mematikan "acara" semacam di aplikasi saya, atau memicu proses panjang.
Ada ide?
php
http
asynchronous
Brent
sumber
sumber
Jawaban:
Jawaban yang sebelumnya saya terima tidak berhasil. Masih menunggu tanggapan. Ini tidak bekerja meskipun, diambil dari Bagaimana cara membuat permintaan GET asynchronous di PHP?
sumber
curl_post_async
dan mendapatkan bahkan upvotes ...Jika Anda mengontrol target yang ingin Anda panggil secara tidak sinkron (mis. "Longtask.php" Anda sendiri), Anda dapat menutup koneksi dari ujung itu, dan kedua skrip akan berjalan secara paralel. Ini berfungsi seperti ini:
Saya sudah mencoba ini, dan itu berfungsi dengan baik. Tetapi quick.php tidak akan tahu apa-apa tentang bagaimana longtask.php lakukan, kecuali jika Anda membuat beberapa alat komunikasi antara proses.
Coba kode ini di longtask.php, sebelum Anda melakukan hal lain. Ini akan menutup koneksi, tetapi masih terus berjalan (dan menekan output apa pun):
Kode disalin dari catatan kontribusi pengguna manual PHP dan agak ditingkatkan.
sumber
while(true);
setelah kode Anda. Halaman akan menggantung, ini berarti masih berjalan di latar depan.Anda dapat melakukan tipu daya dengan menggunakan exec () untuk memanggil sesuatu yang dapat melakukan permintaan HTTP, seperti
wget
, tetapi Anda harus mengarahkan semua output dari program ke suatu tempat, seperti file atau / dev / null, jika tidak, proses PHP akan menunggu output itu .Jika Anda ingin memisahkan proses dari utas apache sepenuhnya, coba sesuatu seperti (Saya tidak yakin tentang ini, tapi saya harap Anda mendapatkan ide):
Ini bukan bisnis yang bagus, dan Anda mungkin ingin sesuatu seperti pekerjaan cron yang menggunakan skrip detak jantung yang menyurvei antrian acara basis data aktual untuk melakukan acara asinkron yang sebenarnya.
sumber
exec("curl $url > /dev/null 2>&1 &");
adalah salah satu solusi tercepat di sini. Ini jauh lebih cepat (1,9 detik untuk 100 iterasi) daripadapost_without_wait()
fungsi (14,8 detik) dalam jawaban "diterima" di atas. DAN itu satuPada 2018, Guzzle telah menjadi perpustakaan standar de facto untuk permintaan HTTP, yang digunakan dalam beberapa kerangka kerja modern. Ini ditulis dalam PHP murni dan tidak perlu menginstal ekstensi khusus.
Ia dapat melakukan panggilan HTTP asinkron dengan sangat baik, dan bahkan menggabungkannya seperti ketika Anda perlu melakukan 100 panggilan HTTP, tetapi tidak ingin menjalankan lebih dari 5 sekaligus.
Contoh permintaan bersamaan
Lihat http://docs.guzzlephp.org/en/stable/quickstart.html#concurrent-requests
sumber
sumber
&
di bagian akhir?Anda dapat menggunakan perpustakaan ini: https://github.com/stil/curl-easy
Maka cukup mudah:
Di bawah ini Anda dapat melihat keluaran konsol dari contoh di atas. Ini akan menampilkan jam langsung sederhana yang menunjukkan berapa banyak permintaan waktu berjalan:
sumber
Palsu aborsi permintaan menggunakan
CURL
pengaturan rendahCURLOPT_TIMEOUT_MS
atur
ignore_user_abort(true)
untuk tetap memproses setelah koneksi ditutup.Dengan metode ini tidak perlu menerapkan penanganan koneksi melalui header dan buffer terlalu tergantung pada versi OS, Browser dan PHP
Proses master
Proses latar belakang
NB
Sumber daya
batas waktu curl kurang dari 1000 ms selalu gagal?
http://www.php.net/manual/en/function.curl-setopt.php#104597
http://php.net/manual/en/features.connection-handling.php
sumber
biarkan saya menunjukkan jalan saya :)
membutuhkan nodejs yang terinstal di server
(server saya mengirim 1000 https, dapatkan permintaan hanya membutuhkan waktu 2 detik)
url.php:
urlscript.js>
sumber
Ekstensi swoole. https://github.com/matyhtf/swoole Asynchronous & concurrent framework jaringan untuk PHP.
sumber
Anda dapat menggunakan soket yang tidak menghalangi dan salah satu ekstensi pecl untuk PHP:
Anda dapat menggunakan pustaka yang memberi Anda lapisan abstraksi antara kode Anda dan ekstensi pecl: https://github.com/reactphp/event-loop
Anda juga dapat menggunakan async http-client, berdasarkan pada pustaka sebelumnya: https://github.com/reactphp/http-client
Lihat perpustakaan ReactPHP lainnya: http://reactphp.org
Hati-hati dengan model asinkron. Saya merekomendasikan untuk melihat video ini di youtube: http://www.youtube.com/watch?v=MWNcItWuKpI
sumber
sumber
Perpanjangan Acara
Perpanjangan acara sangat tepat. Ini adalah port dari perpustakaan Libevent yang dirancang untuk I / O yang digerakkan oleh acara, terutama untuk jaringan.
Saya telah menulis sampel klien HTTP yang memungkinkan untuk menjadwalkan sejumlah permintaan HTTP dan menjalankannya secara tidak sinkron.
Ini adalah contoh kelas klien HTTP berdasarkan ekstensi Acara .
Kelas memungkinkan untuk menjadwalkan sejumlah permintaan HTTP, kemudian menjalankannya secara tidak sinkron.
http-client.php
test.php
Ini adalah contoh skrip di sisi server.
Pemakaian
Output Sampel
(Dipangkas.)
Catatan, kode ini dirancang untuk pemrosesan jangka panjang dalam CLI SAPI .
Untuk protokol khusus, pertimbangkan untuk menggunakan API tingkat rendah, yaitu acara buffer , buffer . Untuk komunikasi SSL / TLS, saya akan merekomendasikan API tingkat rendah bersamaan dengan konteks ssl Acara . Contoh:
Meskipun Libevent's HTTP API sederhana, itu tidak fleksibel seperti acara penyangga. Misalnya, API HTTP saat ini tidak mendukung metode HTTP khusus. Tetapi dimungkinkan untuk mengimplementasikan hampir semua protokol menggunakan API tingkat rendah.
Perpanjangan Ev
Saya juga telah menulis sampel klien HTTP lain menggunakan ekstensi Ev dengan soket dalam mode non-blocking . Kode sedikit lebih verbose daripada sampel berdasarkan pada Peristiwa, karena Ev adalah perulangan peristiwa tujuan umum. Itu tidak menyediakan fungsi-fungsi khusus jaringan, tetapi
EvIo
pengamatnya mampu mendengarkan deskriptor file yang dienkapsulasi ke sumber daya soket, khususnya.Ini adalah contoh klien HTTP berdasarkan ekstensi Ev .
Ekstensi Ev mengimplementasikan loop acara tujuan umum sederhana namun kuat. Itu tidak menyediakan pengamat spesifik jaringan, tetapi pengamat I / O-nya dapat digunakan untuk pemrosesan soket yang tidak sinkron .
Kode berikut menunjukkan bagaimana permintaan HTTP dapat dijadwalkan untuk pemrosesan paralel.
http-client.php
Pengujian
Misalkan
http://my-host.local/test.php
skrip sedang mencetak dump$_GET
:Maka output dari
php http-client.php
perintah akan serupa dengan yang berikut:(dipangkas)
Catatan, di PHP 5 yang soket ekstensi dapat log peringatan untuk
EINPROGRESS
,EAGAIN
danEWOULDBLOCK
errno
nilai-nilai. Dimungkinkan untuk mematikan log denganTentang "Sisa" Kode
Kode yang seharusnya berjalan secara paralel dengan permintaan jaringan dapat dieksekusi dalam panggilan balik dari pengatur waktu Acara , atau pengamat siaga Ev , misalnya. Anda dapat dengan mudah mengetahuinya dengan menonton sampel yang disebutkan di atas. Kalau tidak, saya akan menambahkan contoh lain :)
sumber
Ini adalah contoh yang berfungsi, jalankan saja dan buka storage.txt sesudahnya, untuk memeriksa hasil ajaibnya
sumber
Ini adalah fungsi PHP saya sendiri ketika saya melakukan POST ke URL spesifik halaman mana pun .... Contoh: *** penggunaan Fungsi saya ...
sumber
ReactPHP async http client
https://github.com/shuchkin/react-http-client
Instal melalui Komposer
Async HTTP DAPATKAN
Jalankan php dalam mode CLI
sumber
Saya menemukan paket ini sangat berguna dan sangat sederhana: https://github.com/amphp/parallel-functions
Ini akan memuat semua 3 url secara paralel. Anda juga dapat menggunakan metode instance kelas di penutupan.
Misalnya saya menggunakan ekstensi Laravel berdasarkan paket ini https://github.com/spatie/laravel-collection-macros#parallelmap
Ini kode saya:
Itu memuat semua data yang diperlukan dalam 10 utas paralel dan bukannya 50 detik tanpa async selesai hanya dalam 8 detik.
sumber
Symfony HttpClient adalah asinkron https://symfony.com/doc/current/components/http_client.html .
Misalnya kamu bisa
sumber
Nah, batas waktu dapat diatur dalam milidetik, lihat "CURLOPT_CONNECTTIMEOUT_MS" di http://www.php.net/manual/en/function.curl-setopt
sumber