>  기사  >  백엔드 개발  >  PHP는 실시간으로 출력할 수 없습니다

PHP는 실시간으로 출력할 수 없습니다

WBOY
WBOY원래의
2023-05-07 10:57:08696검색

PHP는 웹 요청 처리 및 데이터베이스 상호 작용과 같은 작업에 일반적으로 사용되는 널리 사용되는 서버 측 스크립팅 언어입니다. 그러나 PHP는 특정 작업을 수행할 때 실시간으로 결과를 출력할 수 없는 것으로 보이며 이는 개발자에게 몇 가지 과제를 제기합니다.

이 기사에서는 PHP가 실시간으로 출력할 수 없는 이유를 살펴보고 몇 가지 해결 방법을 제공합니다.

질문의 배경

PHP는 웹 개발에 널리 사용되는 언어이며 많은 웹 애플리케이션은 PHP를 사용하여 사용자 요청을 처리합니다. 요청을 처리할 때 PHP는 일반적으로 HTML, JSON 또는 XML 문서와 같은 일부 응답을 클라이언트에 보내야 합니다. 이러한 응답은 일반적으로 웹 서버가 클라이언트 요청을 받은 직후 생성되어 전송됩니다. 그러나 어떤 경우에는 PHP가 실시간으로 응답을 출력하지 못하는 것 같습니다.

예를 들어 다음과 같은 간단한 PHP 스크립트를 고려해 보세요.

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

이 스크립트는 단순히 0에서 9까지의 숫자를 출력하며 각 숫자 사이에는 1초의 일시 중지가 있습니다. 그런데 이 스크립트를 웹 브라우저에서 실행하면 10초 후에 모든 숫자가 한꺼번에 출력되는 것을 볼 수 있습니다.

PHP가 페이지가 생성된 후 웹 브라우저로 보내기 때문입니다. 이 경우, PHP는 스크립트 실행이 완료될 때까지 기다렸다가 웹 브라우저로 보내기 전에 전체 페이지를 생성해야 합니다. 이는 스크립트가 실행되는 동안 전체 페이지가 생성될 때까지 웹 브라우저에 아무것도 표시되지 않음을 의미합니다.

이는 일반적으로 대량의 데이터를 처리하거나 외부 웹 서비스와 상호 작용하는 등 장기 실행 작업을 수행해야 할 때 발생합니다. 이 경우 PHP는 결과를 클라이언트에 보내기 전에 전체 작업이 완료될 때까지 기다려야 하며, 이는 몇 초 또는 몇 분이 걸릴 수 있습니다.

문제 원인

PHP가 실시간으로 응답을 출력하지 못하는 이유는 웹 서버가 페이지 응답을 청크 전송 인코딩으로 처리하기 때문입니다.

블록 전송 인코딩은 서버가 응답을 처리할 때 사용되는 HTTP 프로토콜의 스트리밍 기술입니다. 요청의 응답 프로세스가 응답 본문의 길이를 알 수 없는 경우 블록 전송 인코딩 기술은 본문이 전송될 때까지 응답 본문을 블록 단위로 점진적으로 전송합니다.

PHP에서 응답을 출력하기 위해 echo 함수를 사용할 때 PHP는 실제로 응답에 얼마나 많은 데이터를 전송해야 하는지 알지 못합니다. 이는 PHP가 청크 분할 전송 인코딩을 사용하여 응답을 보낼 수 없으며 클라이언트에 보내기 전에 전체 응답 본문이 생성될 때까지 기다려야 함을 의미합니다. 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

이 동작은 PHP의 실시간 출력 기능을 매우 제한하게 만들고 PHP가 큰 응답이 필요한 작업을 효율적으로 처리하지 못하게 합니다.

해결책

PHP가 실시간으로 응답을 출력할 수 없는 문제에 대한 몇 가지 해결 방법이 있습니다:

플러시 기능 사용

PHP는 프로그램이 출력 버퍼의 내용을 즉시 보낼 수 있도록 하는 플러시 기능을 제공합니다. 웹 브라우저 장치. 따라서 스크립트 실행 단계 사이에서 플러시 함수를 호출하여 실시간 출력을 얻을 수 있습니다.

예를 들어 위의 예를 다음과 같이 수정할 수 있습니다. 🎜
<!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>
🎜이 예에서는 각 숫자를 출력한 후 즉시 플러시 함수를 호출합니다. 이는 PHP가 전체 스크립트 실행이 완료될 때까지 기다리지 않고 즉시 웹 브라우저에 출력을 보내도록 지시합니다. 🎜🎜Notes🎜🎜Flush 기능으로 실시간 출력 문제를 해결할 수 있지만, 다른 문제가 발생할 수도 있습니다. 예를 들어 서버의 전송 버퍼가 가득 찬 경우 플러시 함수를 호출하면 서버가 중단되고 버퍼에 전송을 계속할 만큼 충분한 공간이 생길 때까지 기다리게 됩니다. 🎜🎜또한 플러시 기능을 사용하면 성능이 많이 소모되므로 웹 애플리케이션 속도가 느려집니다. 따라서 플러시 기능은 주의해서 사용해야 하며, 과도한 사용은 피해야 합니다. 🎜🎜JavaScript 사용🎜🎜PHP의 실시간 출력 불가 문제를 해결하는 또 다른 방법은 JavaScript를 사용하는 것입니다. JavaScript를 사용하여 웹 브라우저에서 서버로 요청을 보내고 요청에 대한 응답을 페이지의 일부로 표시하는 코드를 작성할 수 있습니다. 🎜🎜예를 들어 위의 예를 다음과 같이 수정할 수 있습니다. 🎜rrreee🎜이 예에서는 JavaScript를 사용하여 매초 서버에 요청을 보내고 div 페이지에 응답을 표시하는 updateOutput 함수를 작성합니다. 코드> 태그. 서버측 처리 스크립트 <code>output.php는 위의 예와 동일하며 0부터 9까지의 숫자를 출력합니다. 🎜🎜마지막 setInterval 함수는 updateOutput 함수를 호출하는데, 이 함수는 매초마다 updateOutput 함수를 호출합니다. 이로 인해 매 두 번째 응답이 웹 브라우저로 전송되어 페이지에 표시됩니다. 🎜🎜Notes🎜🎜JavaScript를 사용하면 실시간 출력 문제를 해결할 수 있지만 몇 가지 문제도 있습니다. 첫째, 간헐적인 통화를 사용하기 때문에 웹 브라우저와 서버 사이에 네트워크 트래픽이 더 많이 발생하여 네트워크 부하가 증가합니다. 🎜🎜또한 JavaScript 솔루션은 플러시 기능을 사용할 때와 동일한 성능 문제를 겪습니다. 실시간 출력을 처리하기 위해 너무 많은 JavaScript 코드를 추가하면 웹 애플리케이션의 성능에 심각한 영향을 미칩니다. 🎜🎜WebSocket 사용🎜🎜WebSocket은 웹 애플리케이션에서 실시간 데이터를 전송하기 위한 표준으로, 양방향 통신을 위해 클라이언트와 서버 간의 장기적인 연결을 허용합니다. 🎜

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

위 내용은 PHP는 실시간으로 출력할 수 없습니다의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.