Masalah
saya memiliki formulir yang, ketika dikirimkan, akan menjalankan kode dasar untuk memproses informasi yang dikirimkan dan memasukkannya ke dalam database untuk ditampilkan di situs web notifikasi. Selain itu, saya memiliki daftar orang yang telah mendaftar untuk menerima pemberitahuan ini melalui email dan pesan SMS. Daftar ini sepele saat ini (hanya mendorong sekitar 150), namun cukup untuk menyebabkan perlu lebih dari satu menit untuk menelusuri seluruh tabel pelanggan dan mengirim 150+ email. (Email dikirim secara individual seperti yang diminta oleh administrator sistem server email kami karena kebijakan email massal.)
Selama waktu ini, individu yang mengeposkan lansiran akan duduk di halaman terakhir formulir selama hampir satu menit tanpa penguatan positif bahwa pemberitahuan mereka sedang diposkan. Hal ini menyebabkan masalah potensial lainnya, semua itu memiliki solusi yang mungkin saya rasa kurang ideal.
Pertama, pengepos mungkin mengira server sedang lamban dan mengklik tombol 'Kirim' lagi, menyebabkan skrip dimulai kembali atau dijalankan dua kali. Saya bisa menyelesaikan ini dengan menggunakan JavaScript untuk menonaktifkan tombol dan mengganti teks untuk mengatakan sesuatu seperti 'Memproses ...', namun ini kurang dari ideal karena pengguna masih akan terjebak di halaman selama eksekusi skrip. (Selain itu, jika JavaScript dinonaktifkan, masalah ini masih ada.)
Kedua, poster mungkin menutup tab atau browser sebelum waktunya setelah mengirimkan formulir. Skrip akan terus berjalan di server hingga mencoba menulis kembali ke browser, namun jika pengguna kemudian menjelajahi halaman mana pun dalam domain kami (saat skrip masih berjalan), browser berhenti memuat halaman sampai skrip selesai . (Ini hanya terjadi ketika tab atau jendela browser ditutup dan bukan seluruh aplikasi browser.) Tetap saja, ini kurang dari ideal.
(Kemungkinan) Solusi
Saya telah memutuskan untuk membagi bagian "email" dari skrip menjadi file terpisah yang dapat saya panggil setelah pemberitahuan dikirim. Saya awalnya berpikir untuk meletakkan ini di halaman konfirmasi setelah pemberitahuan berhasil diposting. Namun, pengguna tidak akan tahu skrip ini sedang berjalan dan semua anomali tidak akan terlihat oleh mereka; Skrip ini tidak boleh gagal.
Tetapi, bagaimana jika saya dapat menjalankan skrip ini sebagai proses latar belakang? Jadi, pertanyaan saya adalah ini: Bagaimana saya dapat menjalankan skrip PHP untuk memicu sebagai layanan latar belakang dan berjalan sepenuhnya terlepas dari apa yang telah dilakukan pengguna di tingkat formulir?
EDIT: Ini tidak dapat di-cron'ed. Ini harus berjalan segera setelah formulir dikirimkan. Ini adalah pemberitahuan dengan prioritas tinggi. Selain itu, administrator sistem yang menjalankan server kami melarang crons berjalan lebih dari 5 menit.
sumber
exec()
tetapi saya tidak pernah mencoba ini.ajax
dan memasukkansleep()
dengan interval waktu di dalam loop (saya menggunakan foreach dalam kasus saya) untuk menjalankan proses latar belakang. Ia bekerja dengan sempurna di server saya. Tidak yakin mengenai yang lain. Saya juga menambahkanignore_user_abort()
danset_time_limit()
(dengan waktu akhir yang dihitung) sebelum loop untuk memastikan bahwa skrip tidak akan dihentikan oleh server yang saya gunakan, bahkan menurut pengujian saya, skrip menyelesaikan tugas tanpaignore_user_abort()
danset_time_limit()
.gearman
php untuk menangani tugas latar belakang. Ini sempurna untuk menskalakan jika Anda menemukan pemrosesan waktu yang lama dan beban berat. Anda harus memeriksanya.Jawaban:
Melakukan beberapa eksperimen dengan
exec
danshell_exec
saya telah menemukan solusi yang bekerja dengan sempurna! Saya memilih untuk menggunakanshell_exec
sehingga saya dapat mencatat setiap proses pemberitahuan yang terjadi (atau tidak). (shell_exec
dikembalikan sebagai string dan ini lebih mudah daripada menggunakanexec
, menetapkan keluaran ke variabel dan kemudian membuka file untuk menulis.)Saya menggunakan baris berikut untuk menjalankan skrip email:
Penting untuk memperhatikan
&
di akhir perintah (seperti yang ditunjukkan oleh @netcoder). Perintah UNIX ini menjalankan proses di latar belakang.Variabel ekstra yang diapit tanda kutip tunggal setelah jalur ke skrip ditetapkan sebagai
$_SERVER['argv']
variabel yang dapat saya panggil dalam skrip saya.Skrip email kemudian menampilkan file log saya menggunakan
>>
dan akan menampilkan sesuatu seperti ini:sumber
$post_id
setelah jalur skrip php?$post_id
; Saya lebih suka dilemparkan langsung ke nomor:(int) $post_id
. (Memanggil perhatian Anda untuk memutuskan mana yang lebih baik.)Di server Linux / Unix, Anda dapat menjalankan pekerjaan di latar belakang dengan menggunakan proc_open :
The
&
menjadi sedikit penting di sini. Skrip akan terus berlanjut meskipun skrip asli telah berakhir.sumber
proc_close
ketika tugas telah selesai.proc_close
membuat skrip hang sekitar 15 hingga 25 detik. Saya perlu menyimpan log menggunakan informasi pipa, jadi saya harus membuka file yang akan ditulis, menutupnya, dan kemudian menutup koneksi proc. Jadi, sayangnya, solusi ini tidak berhasil untuk saya.proc_close
, itulah intinya! Dan ya, Anda bisa menyalurkan ke file denganproc_open
. Lihat jawaban yang diperbarui.Dari semua jawaban, tidak ada yang menganggap fungsi fastcgi_finish_request yang sangat mudah , yang ketika dipanggil, membuang semua output yang tersisa ke browser dan menutup sesi Fastcgi dan koneksi HTTP, sambil membiarkan skrip berjalan di latar belakang.
Sebuah contoh:
sumber
PHP
exec("php script.php")
bisa melakukannya.Dari Manual :
Jadi jika Anda mengarahkan output ke file log (bagaimanapun juga ide yang bagus), skrip pemanggil Anda tidak akan hang dan skrip email Anda akan berjalan di bg.
sumber
Dan mengapa tidak membuat Permintaan HTTP pada skrip dan mengabaikan responsnya?
http://php.net/manual/en/function.httprequest-send.php
Jika Anda membuat permintaan pada skrip, Anda perlu memanggil server web Anda akan menjalankannya di latar belakang dan Anda dapat (di skrip utama Anda) menampilkan pesan yang memberi tahu pengguna bahwa skrip sedang berjalan.
sumber
Bagaimana dengan ini?
Skrip PHP kedua ini harus diatur untuk dijalankan sebagai cron.
sumber
Seperti yang saya tahu Anda tidak dapat melakukan ini dengan cara yang mudah (lihat fork exec dll (tidak berfungsi di bawah windows)), mungkin Anda dapat membalikkan pendekatan, gunakan latar belakang browser untuk memposting formulir di ajax, jadi jika posting masih bekerja, Anda tidak perlu menunggu waktu.
Ini dapat membantu bahkan jika Anda harus melakukan elaborasi yang panjang.
Tentang pengiriman email selalu disarankan untuk menggunakan spooler, mungkin server smtp lokal & cepat yang menerima permintaan Anda dan spool mereka ke MTA yang sebenarnya atau meletakkan semuanya di DB, daripada menggunakan cron yang spool antrian.
Cron mungkin berada di komputer lain yang memanggil spooler sebagai url eksternal:
sumber
Pekerjaan cron latar belakang terdengar seperti ide bagus untuk ini.
Anda memerlukan akses ssh ke mesin untuk menjalankan skrip sebagai cron.
$ php scriptname.php
untuk menjalankannya.sumber
Jika Anda dapat mengakses server melalui ssh dan dapat menjalankan skrip Anda sendiri, Anda dapat membuat server fifo sederhana menggunakan php (meskipun Anda harus mengkompilasi ulang php dengan
posix
dukungan untukfork
).Server dapat ditulis dalam apa saja, Anda mungkin dapat dengan mudah melakukannya dengan python.
Atau solusi paling sederhana akan mengirimkan HttpRequest dan tidak membaca data yang dikembalikan tetapi server mungkin menghancurkan skrip sebelum selesai diproses.
Contoh server:
Contoh klien:
sumber
Cara paling sederhana untuk menjalankan skrip PHP di latar belakang adalah
Script akan berjalan di background dan halaman juga akan mencapai halaman tindakan lebih cepat.
sumber
Dengan asumsi Anda berjalan pada platform * nix, gunakan
cron
danphp
eksekusi.EDIT:
Ada cukup banyak pertanyaan yang menanyakan untuk "menjalankan php tanpa cron" di SO. Ini dia:
Jadwalkan skrip tanpa menggunakan CRON
Konon, jawaban exec () di atas terdengar sangat menjanjikan :)
sumber
Jika Anda menggunakan Windows, teliti
proc_open
ataupopen
...Tetapi jika kita berada di server yang sama "Linux" yang menjalankan cpanel maka ini adalah pendekatan yang tepat:
Jangan gunakan
fork()
ataucurl
jika Anda ragu Anda dapat menanganinya, itu seperti menyalahgunakan server AndaTerakhir, pada
script.php
file yang disebut di atas, perhatikan ini pastikan Anda menulis:sumber
untuk pekerja latar belakang saya pikir Anda harus mencoba teknik ini, ini akan membantu untuk memanggil sebanyak halaman yang Anda suka semua halaman akan berjalan sekaligus secara independen tanpa menunggu respons setiap halaman sebagai asynchronous.
form_action_page.php
testpage.php
PS: jika Anda ingin mengirim parameter url sebagai loop, ikuti jawaban ini: https://stackoverflow.com/a/41225209/6295712
sumber
Dalam kasus saya, saya memiliki 3 params, salah satunya adalah string (mensaje):
Di Process.php saya, saya memiliki kode ini:
sumber
Ini berhasil untuk saya. tyr ini
sumber
serialize()
fungsi. sebagai contoh, saya memilikiindex.php
formulir dan saya mengirim nilai melalui ajax ke index2.php Saya ingin melakukan pengiriman data di index2.php di latar belakang apa yang Anda sarankan? terima kasihGunakan Amphp untuk menjalankan pekerjaan secara paralel & asinkron.
Instal perpustakaan
Contoh kode
Untuk kasus penggunaan Anda, Anda dapat melakukan sesuatu seperti di bawah ini
sumber