Maison >développement back-end >Problème PHP >php ne peut pas sortir en temps réel

php ne peut pas sortir en temps réel

WBOY
WBOYoriginal
2023-05-07 10:57:08748parcourir

PHP est un langage de script côté serveur largement utilisé pour des tâches telles que le traitement des requêtes Web et l'interaction avec des bases de données. Cependant, PHP semble incapable de produire des résultats en temps réel lors de l'exécution de certaines tâches, ce qui pose certains défis aux développeurs.

Cet article examinera les raisons pour lesquelles PHP ne peut pas produire en temps réel et proposera des solutions.

Contexte de la question

PHP est un langage largement utilisé dans le développement Web et de nombreuses applications Web utilisent PHP pour gérer les demandes des utilisateurs. Lors du traitement d'une requête, PHP doit généralement envoyer une réponse au client, telle qu'un document HTML, JSON ou XML. Ces réponses sont généralement générées et envoyées immédiatement après que le serveur Web reçoit la demande du client. Cependant, dans certains cas, PHP semble incapable d'afficher la réponse en temps réel.

Par exemple, considérons le simple script PHP suivant :

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

Ce script affiche simplement les nombres de 0 à 9, avec une pause d'une seconde entre chaque nombre. Cependant, lorsque nous exécutons ce script dans un navigateur Web, nous constatons qu'après 10 secondes, tous les nombres sont affichés en même temps.

En effet, PHP envoie la page au navigateur Web après sa génération. Dans ce cas, PHP doit attendre la fin de l'exécution du script et générer la page entière avant de l'envoyer au navigateur Web. Cela signifie que pendant l'exécution du script, le navigateur Web ne verra rien tant que la page entière n'aura pas été générée.

Cela se produit généralement lorsque vous devez effectuer des tâches de longue durée, telles que le traitement de grandes quantités de données ou l'interaction avec des services Web externes. Dans ce cas, PHP doit attendre que la tâche entière soit terminée avant d'envoyer les résultats au client, ce qui peut prendre quelques secondes ou minutes.

La raison du problème

La raison pour laquelle PHP ne peut pas afficher la réponse en temps réel est que le serveur Web traite la réponse de la page dans un codage de transfert fragmenté.

L'encodage par bloc-transfert est une technologie de streaming dans le protocole HTTP utilisée lorsque le serveur traite les réponses. Lorsque le processus de réponse à la demande ne connaît pas la longueur du corps de la réponse, la technologie de codage par transfert de blocs transmettra progressivement le corps de la réponse en unités de blocs jusqu'à ce que le corps soit envoyé.

En PHP, lorsque nous utilisons la fonction echo pour générer une réponse, PHP ne sait pas réellement combien de données doivent être envoyées dans la réponse. Cela signifie que PHP ne peut pas envoyer la réponse en utilisant le codage de transfert fragmenté et doit attendre que l'intégralité du corps de la réponse soit générée avant de l'envoyer au client. echo函数输出响应时,PHP实际上并不知道在该响应中有多少数据需要发送。这意味着PHP无法使用块传输编码来发送响应,而必须等待整个响应体生成完毕后再将其发送到客户端。

这种行为使得PHP的实时输出功能非常受限,并且使PHP不能有效地处理需要大量响应的任务。

解决方案

针对PHP无法实时输出响应的问题,有几种解决方案:

使用flush函数

PHP提供了一个flush函数,该函数允许程序立即将输出缓冲区的内容发送到Web浏览器。因此,我们可以在脚本执行的步骤之间调用flush函数来实现实时输出。

例如,我们可以将上面的例子修改为:

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

在这个例子中,我们在输出每个数字之后立即调用flush函数。这告诉PHP立即将输出发送到Web浏览器,而不必等待整个脚本执行完毕。

注意点

尽管flush函数可以解决实时输出的问题,但它可能会导致其他问题。例如,如果服务器的发送缓冲区已满,调用flush函数会导致服务器挂起,并等待到缓冲区有足够的空间可以继续发送。

此外,由于使用flush函数是性能开销很大的,因此会使Web应用程序变得缓慢。因此,应该谨慎使用flush函数,避免过度使用。

使用 JavaScript

另一种解决PHP无法实时输出的方法是使用JavaScript。我们可以使用JavaScript编写一些代码来从Web浏览器向服务器发送请求,并将请求的响应作为页面的一部分显示。

例如,我们可以将上面的例子修改为:

<!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>

在这个例子中,我们使用JavaScript编写了一个函数updateOutput,该函数在每一秒钟向服务器发送一个请求,并将响应显示在页面的div标签上。服务器端的处理脚本output.php与上面的例子相同,它输出从0到9的数字。

注意,最后的setInterval

Ce comportement rend les capacités de sortie en temps réel de PHP très limitées et empêche PHP de gérer efficacement les tâches nécessitant des réponses volumineuses.

Solution

Il existe plusieurs solutions au problème selon lequel PHP ne peut pas générer de réponse en temps réel :

Utilisez la fonction de vidage

PHP fournit une fonction de vidage qui permet au programme d'envoyer immédiatement le contenu du tampon de sortie au périphérique de navigateur Web. Par conséquent, nous pouvons appeler la fonction flush entre les étapes d’exécution du script pour obtenir une sortie en temps réel.

Par exemple, nous pouvons modifier l'exemple ci-dessus en : 🎜
<!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>
🎜Dans cet exemple, nous appelons la fonction flush immédiatement après avoir sorti chaque nombre. Cela indique à PHP d'envoyer immédiatement la sortie au navigateur Web sans attendre la fin de l'exécution complète du script. 🎜🎜Remarques🎜🎜Bien que la fonction de rinçage puisse résoudre le problème de la sortie en temps réel, elle peut causer d'autres problèmes. Par exemple, si le tampon d'envoi du serveur est plein, l'appel de la fonction flush entraînera le blocage du serveur et l'attente jusqu'à ce qu'il y ait suffisamment d'espace dans le tampon pour continuer l'envoi. 🎜🎜De plus, comme l'utilisation de la fonction flush est gourmande en performances, cela ralentira l'application Web. Par conséquent, la fonction de chasse d’eau doit être utilisée avec prudence et une utilisation excessive doit être évitée. 🎜🎜Utilisez JavaScript🎜🎜Une autre façon de résoudre l'incapacité de PHP à produire en temps réel consiste à utiliser JavaScript. Nous pouvons écrire du code en utilisant JavaScript pour envoyer une requête du navigateur Web au serveur et afficher la réponse de la requête dans le cadre de la page. 🎜🎜Par exemple, nous pouvons modifier l'exemple ci-dessus en : 🎜rrreee🎜Dans cet exemple, nous utilisons JavaScript pour écrire une fonction updateOutput qui envoie une requête au serveur toutes les secondes et affiche la réponse sur la page div code> balise. Le script de traitement côté serveur <code>output.php est le même que l'exemple ci-dessus, il génère des nombres de 0 à 9. 🎜🎜Notez que la dernière fonction setInterval appelle la fonction updateOutput, qui appelle la fonction updateOutput une fois par seconde. Cela entraîne l'envoi d'une réponse sur deux au navigateur Web et son affichage sur la page. 🎜🎜Notes🎜🎜Bien que l'utilisation de JavaScript puisse résoudre le problème de la sortie en temps réel, elle présente également quelques problèmes. Premièrement, puisque les appels intermittents sont utilisés, davantage de trafic réseau est créé entre le navigateur Web et le serveur, ce qui entraîne une augmentation de la charge réseau. 🎜🎜De plus, la solution JavaScript souffre des mêmes problèmes de performances que l'utilisation de la fonction flush. Si vous ajoutez trop de code JavaScript pour gérer la sortie en temps réel, les performances de votre application Web seront gravement affectées. 🎜🎜Utilisation de WebSocket🎜🎜WebSocket est une norme de transmission de données en temps réel dans les applications Web. Elle permet des connexions à long terme entre les clients et les serveurs pour une communication bidirectionnelle. 🎜

我们可以使用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应用程序的性能产生负面影响。因此,在选择解决方案时,请慎重考虑其适合您的特定需求。

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Article précédent:php supprime le précédentArticle suivant:php supprime le précédent