Rumah >pembangunan bahagian belakang >masalah PHP >php tidak boleh mengeluarkan dalam masa nyata

php tidak boleh mengeluarkan dalam masa nyata

WBOY
WBOYasal
2023-05-07 10:57:08784semak imbas

PHP ialah bahasa skrip bahagian pelayan yang digunakan secara meluas yang biasa digunakan untuk tugasan seperti memproses permintaan web dan berinteraksi dengan pangkalan data. Walau bagaimanapun, PHP nampaknya tidak dapat mengeluarkan hasil dalam masa nyata apabila melaksanakan tugas tertentu, yang menimbulkan beberapa cabaran untuk pembangun.

Artikel ini akan menyelidiki sebab PHP tidak dapat mengeluarkan dalam masa nyata dan menyediakan beberapa penyelesaian.

Latar belakang masalah

PHP ialah bahasa yang digunakan secara meluas dalam pembangunan web, dan banyak aplikasi web menggunakan PHP untuk mengendalikan permintaan pengguna. Semasa memproses permintaan, PHP biasanya diperlukan untuk menghantar beberapa respons kepada klien, seperti dokumen HTML, JSON atau XML. Respons ini biasanya dijana dan dihantar serta-merta selepas pelayan web menerima permintaan pelanggan. Walau bagaimanapun, dalam beberapa kes PHP nampaknya tidak dapat mengeluarkan respons dalam masa nyata.

Sebagai contoh, pertimbangkan skrip PHP mudah berikut:

<?php
for ($i = 0; $i < 10; $i++) {
    echo "$i\n";
    sleep(1);
}
?>

Skrip ini hanya mengeluarkan nombor dari 0 hingga 9, berhenti seketika selama 1 saat antara setiap nombor. Walau bagaimanapun, apabila kami menjalankan skrip ini dalam pelayar web, kami mendapati bahawa selepas 10 saat, semua nombor dikeluarkan serentak.

Ini kerana PHP menghantar halaman ke penyemak imbas web selepas ia dijana. Dalam kes ini, PHP perlu menunggu skrip selesai melaksanakan dan menjana keseluruhan halaman sebelum menghantarnya ke pelayar web. Ini bermakna semasa skrip berjalan, pelayar web tidak akan melihat apa-apa sehingga keseluruhan halaman telah dijana.

Ini biasanya berlaku apabila anda perlu melakukan tugasan yang berjalan lama, seperti memproses sejumlah besar data atau berinteraksi dengan perkhidmatan web luaran. Dalam kes ini, PHP perlu menunggu sehingga keseluruhan tugasan selesai sebelum menghantar keputusan kepada pelanggan, yang boleh mengambil masa beberapa saat atau minit.

Punca masalah

Sebab mengapa PHP tidak dapat mengeluarkan respons dalam masa nyata adalah kerana pelayan web memproses respons halaman dalam pengekodan pemindahan chunked.

Pengekodan pemindahan blok ialah teknologi penstriman dalam protokol HTTP yang digunakan apabila pelayan memproses respons. Apabila proses tindak balas permintaan tidak mengetahui panjang badan tindak balas, teknologi pengekodan pemindahan blok akan secara beransur-ansur menghantar badan tindak balas dalam unit blok sehingga badan dihantar.

Dalam PHP, apabila kita menggunakan fungsi echo untuk mengeluarkan respons, PHP sebenarnya tidak tahu berapa banyak data yang perlu dihantar dalam respons itu. Ini bermakna PHP tidak boleh menghantar respons menggunakan pengekodan pemindahan chunked dan mesti menunggu seluruh badan respons dijana sebelum menghantarnya kepada klien.

Tingkah laku ini menjadikan keupayaan output masa nyata PHP sangat terhad dan menghalang PHP daripada mengendalikan tugas dengan cekap yang memerlukan respons yang besar.

Penyelesaian

Untuk masalah PHP tidak dapat mengeluarkan respons dalam masa nyata, terdapat beberapa penyelesaian:

Gunakan fungsi flush

PHP menyediakan fungsi flush , fungsi ini membolehkan program menghantar kandungan penimbal keluaran dengan segera ke pelayar web. Oleh itu, kita boleh memanggil fungsi flush antara langkah-langkah pelaksanaan skrip untuk mencapai output masa nyata.

Sebagai contoh, kita boleh mengubah suai contoh di atas kepada:

<?php
for ($i = 0; $i < 10; $i++) {
    echo "$i\n";
    flush();
    sleep(1);
}
?>

Dalam contoh ini, kita memanggil fungsi flush serta-merta selepas mengeluarkan setiap nombor. Ini memberitahu PHP untuk menghantar output ke penyemak imbas web dengan segera tanpa menunggu keseluruhan skrip selesai dilaksanakan.

Nota

Walaupun fungsi flush boleh menyelesaikan masalah output masa nyata, ia mungkin menyebabkan masalah lain. Sebagai contoh, jika penimbal hantar pelayan penuh, memanggil fungsi siram akan menyebabkan pelayan digantung dan menunggu sehingga terdapat ruang yang cukup dalam penimbal untuk meneruskan penghantaran.

Selain itu, memandangkan penggunaan fungsi flush adalah intensif prestasi, ia akan menjadikan aplikasi web menjadi perlahan. Oleh itu, fungsi flush harus digunakan dengan berhati-hati dan penggunaan yang berlebihan harus dielakkan.

Gunakan JavaScript

Cara lain untuk menyelesaikan masalah yang PHP tidak dapat keluarkan dalam masa nyata ialah menggunakan JavaScript. Kami boleh menulis beberapa kod menggunakan JavaScript untuk menghantar permintaan daripada pelayar web ke pelayan dan memaparkan respons permintaan sebagai sebahagian daripada halaman.

Sebagai contoh, kami boleh mengubah suai contoh di atas kepada:

<!DOCTYPE html>
<html>
<head>
    <title>Real-time PHP Output Example</title>
    <script type="text/javascript">
        function updateOutput() {
            var xhr = new XMLHttpRequest();
            xhr.onreadystatechange = function() {
                if (xhr.readyState === 4 && xhr.status === 200) {
                    document.getElementById("output").innerHTML += xhr.responseText;
                }
            };
            xhr.open("GET", "output.php", true);
            xhr.send();
        }
        setInterval(updateOutput, 1000);
    </script>
</head>
<body>
    <div id="output"></div>
</body>
</html>

Dalam contoh ini, kami menulis fungsi kemas kiniOutput dalam JavaScript yang menghantar permintaan kepada pelayan setiap saat , dan memaparkan respons pada tag div halaman. Skrip pemprosesan sebelah pelayan output.php adalah sama seperti contoh di atas, ia mengeluarkan nombor dari 0 hingga 9.

Perhatikan bahawa fungsi setInterval terakhir memanggil fungsi updateOutput, yang memanggil fungsi updateOutput sekali setiap saat. Ini menyebabkan setiap respons kedua dihantar ke pelayar web dan dipaparkan pada halaman.

Nota

Walaupun menggunakan JavaScript boleh menyelesaikan masalah output masa nyata, ia juga mempunyai beberapa masalah. Pertama, sejak panggilan terputus-putus digunakan, lebih banyak trafik rangkaian dibuat antara penyemak imbas web dan pelayan, mengakibatkan beban rangkaian meningkat.

Selain itu, penyelesaian JavaScript mengalami masalah prestasi yang sama seperti menggunakan fungsi siram. Jika anda menambah terlalu banyak kod JavaScript untuk mengendalikan output masa nyata, prestasi aplikasi web anda akan terjejas teruk.

Menggunakan WebSocket

WebSocket ialah standard untuk menghantar data masa nyata dalam aplikasi web Ia membolehkan sambungan jangka panjang antara pelanggan dan pelayan untuk komunikasi dua hala.

我们可以使用WebSocket解决PHP无法实时输出的问题。当PHP向WebSocket服务器发送数据时,服务器可以立即将其转发给客户端,实现实时输出。

例如,我们可以将上述例子改成使用WebSocket:

<!DOCTYPE html>
<html>
<head>
    <title>Real-time PHP Output Example</title>
    <script type="text/javascript">
        var ws = new WebSocket("ws://localhost:8080/");
        ws.onmessage = function(event) {
            var output = document.getElementById("output");
            output.innerHTML += event.data;
        };
    </script>
</head>
<body>
    <div id="output"></div>
</body>
</html>

在这个例子中,我们使用JavaScript创建了一个WebSocket实例,并将其连接到一个WebSocket服务器。当服务器向客户端发送消息时,我们使用JavaScript将其显示在页面上。

在服务器端,我们可以使用PHP与WebSocket协议进行通信。PHP提供了一些WebSocket库,例如Ratchet(http://socketo.me/),可以方便地实现WebSocket协议。

注意点

虽然WebSocket提供了一种双向通信的实时数据传输协议,但它在实现时需要额外的工作。WebSocket需要与PHP结合使用,以便将实时输出响应发送到客户端。这使得使用WebSocket的实现更加复杂,并需要其他技术的帮助。

结论

PHP无法实时输出响应通常是因为Web服务器使用了块传输编码。这通常发生在需要执行长时间运行的任务时,例如处理大量数据或与外部Web服务交互。为了解决这个问题,我们可以使用flush函数、JavaScript和WebSocket等方案。这些解决方案都有一些限制,并且可能会对Web应用程序的性能产生负面影响。因此,在选择解决方案时,请慎重考虑其适合您的特定需求。

Atas ialah kandungan terperinci php tidak boleh mengeluarkan dalam masa nyata. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Artikel sebelumnya:php keluarkan yang sebelumnyaArtikel seterusnya:php keluarkan yang sebelumnya