返回顶部
分享到

PHP+HTML实现流式输出效果的示例

php 来源:互联网 作者:佚名 发布时间:2025-06-04 21:39:04 人浏览
摘要

效果演示 后端代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 ?php // 关闭输出缓冲 ini_set(output_buffering, off); ini_set(zlib.output_compression, false); while (ob_get

效果演示

后端代码

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

<?php

// 关闭输出缓冲

ini_set('output_buffering', 'off');

ini_set('zlib.output_compression', false);

while (ob_get_level()) ob_end_clean(); // 清除所有缓冲层

 

// 设置HTTP头(流式内容类型 + 禁用缓存)

header('Content-Type: text/plain; charset=utf-8');

header('Cache-Control: no-cache');

header('X-Accel-Buffering: no');

 

// 模拟对话回复内容

$messages = [

    "你好!我正在分析您的问题...\n",

    "已找到相关解决方案,请稍等。\n",

    "处理完成!以下是详细回答:\n"

];

 

// 流式输出每条消息

foreach ($messages as $msg) {

    // 逐字输出(可选)

    // $length = strlen($msg);

    $length = mb_strlen($msg);

    for ($i=0; $i<$length; $i++) {

        // echo $msg[$i];

        $char = mb_substr($msg, $i, 1, 'UTF-8');

        echo $char;

        ob_flush(); // 刷新PHP缓冲

        flush();    // 刷新Web服务器缓冲

        usleep(50000); // 50ms延迟模拟打字效果

    }

}

 

// 持续生成内容的例子(如从数据库/API获取)

for ($i=1; $i<=5; $i++) {

    echo "正在处理第 {$i} 项任务...\n";

    ob_flush();

    flush();

    sleep(1);

}

前端代码

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>智能客服系统</title>

    <style>

        body {

            font-family: Arial, sans-serif;

            display: flex;

            justify-content: center;

            align-items: center;

            height: 100vh;

            margin: 0;

            background-color: #f4f4f9;

        }

        .chat-container {

            width: 800px;

            background-color: #fff;

            border-radius: 10px;

            box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);

            padding: 20px;

        }

        .messages {

            height: 500px;

            overflow-y: auto;

            border-bottom: 1px solid #ddd;

            padding-bottom: 10px;

        }

        .message {

            margin: 10px 0;

        }

        .user {

            text-align: right;

        }

        .bot {

            text-align: left;

        }

        .input-container {

            display: flex;

            margin-top: 10px;

        }

        .input-container input {

            flex: 1;

            padding: 10px;

            border: 1px solid #ddd;

            border-radius: 5px;

        }

        .input-container button {

            padding: 10px 20px;

            border: none;

            background-color: #007bff;

            color: #fff;

            border-radius: 5px;

            cursor: pointer;

        }

        .input-container button:hover {

            background-color: #0056b3;

        }

    </style>

</head>

<body>

<div class="chat-container">

    <div class="messages" id="messages" style="white-space: pre-wrap;"></div>

    <div class="input-container">

        <input type="text" id="userInput" placeholder="输入消息...">

        <button onclick="sendMessage()">发送</button>

    </div>

</div>

 

<script>

    function sendMessage() {

        const userInput = document.getElementById('userInput').value;

        if (userInput.trim() === '') return;

        document.getElementById('userInput').value = '';

 

        const messagesContainer = document.getElementById('messages');

        const userMessage = document.createElement('div');

        userMessage.className = 'message user';

        userMessage.textContent = userInput;

        messagesContainer.appendChild(userMessage);

 

 

        fetch('stream.php')

            .then(response => {

                const reader = response.body.getReader();

                const decoder = new TextDecoder('utf-8');

 

                const botMessage = document.createElement('div');

                botMessage.className = 'message bot';

                messagesContainer.appendChild(botMessage);

 

                function readChunk() {

                    return reader.read().then(({ done, value }) => {

                        if (done) return;

                        // 将二进制数据解码为文本

                        const text = decoder.decode(value);

                        // 实时追加到页面

                        botMessage.innerHTML += text;

                        messagesContainer.scrollTop = messagesContainer.scrollHeight;

                        // 继续读取下一块

                        return readChunk();

                    });

                }

                return readChunk();

            })

            .catch(console.error);

    }

</script>

</body>

</html>

运行测试

项目根目录下打开命令行输入以下命令,执行

1

php -S 127.0.0.1:6789

打开浏览器,输入 127.0.0.1:6789 访问Web界面,输入任意内容发送后,即可看到流式输出效果

原理解析

1. 什么是流式输出

流式输出通常指的是在数据生成的同时逐步发送到客户端,而不是等待所有处理完成后再一次性发送。这在实时聊天应用或需要逐步显示结果的场景中很常见。

2. PHP怎么做到流式输出

PHP默认是缓冲输出的,也就是说,脚本执行完毕后才会将内容发送到浏览器。所以需要调整输出缓冲的设置。比如调用ob_flush()和flush()来实时发送内容。

3. 前端处理数据的接收和显示

前端监听来自服务器的事件,每次接收到数据就更新页面。本次实践通过Fetch读取流式响应体,逐块处理。


版权声明 : 本文内容来源于互联网或用户自行发布贡献,该文观点仅代表原作者本人。本站仅提供信息存储空间服务和不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权, 违法违规的内容, 请发送邮件至2530232025#qq.cn(#换@)举报,一经查实,本站将立刻删除。
原文链接 :
相关文章
  • PHP调用Workerman5.0实现一对一聊天
    要实现一对一聊天功能,使用 Workerman 5.0 作为后端,前端可以使用 WebSocket 进行通信。以下是实现步骤和代码示例。 1. 安装 Workerman 首先,确
  • PHP跨文件传递参数的8种常见方法
    以下是 PHP 中跨文件传递参数的8 种常见方法,按场景和安全性分类整理,附详细说明和示例代码: 一、超全局变量(适合请求间数据共享)
  • PHP+HTML实现流式输出效果的示例

    PHP+HTML实现流式输出效果的示例
    效果演示 后端代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 ?php // 关闭输出缓冲 ini_set(output_bu
  • 在PHP中使用__dir__的详细介绍
    __DIR__ 可以用来获取当前代码工作目录。它从PHP 5.3版本开始引入。它类似于使用 dirname(__FILE__)。通常用于包含其他文件,这些文件存在于一
  • 使用Webman构建高效的音频流媒体应用程序的介绍
    Webmen是一个基于Node.js的Web框架,它提供了一套强大的工具和库,用于构建高效的Web应用程序。它采用了异步和非阻塞的方式处理客户端请求
  • PHP中利用百度地图API实现地图热区的响应效果教
    在开发网站或应用程序时,我们经常会需要在地图上展示热区的信息,这种热区可以是指定区域内的热门活动、人流密集的地方等。百度地
  • PHP打包部署的实践全过程解析
    一、引言 随着项目规模的增大,传统的手动部署方式已经不能满足需求,代码过程繁琐、易出错且效率低下。因此,自动化打包和部署成为
  • PHP数据加密方式的总结

    PHP数据加密方式的总结
    首先我们来了解一下为什么要加密? 在网络通信的过程中攻击者可以伪造请求和返回,从而达到不可告人的目的。如下图所示: 数据加密之
  • PHP四种统计在线人数方式介绍

    PHP四种统计在线人数方式介绍
    1 用表统计方式 用数据表统计在线人数,这种方式只能用在并发量不大的情况下。 首先我们先新建表:user_login 编辑 user_login 表 模拟用户登
  • PHP获取系统毫秒数时间方法
    前言 php中获取时间方法是date(),在php中获取时间戳方法有time()、strtotime(); date():date(format, timestamp),format为格式、timestamp为时间戳(可选
  • 本站所有内容来源于互联网或用户自行发布,本站仅提供信息存储空间服务,不拥有版权,不承担法律责任。如有侵犯您的权益,请您联系站长处理!
  • Copyright © 2017-2022 F11.CN All Rights Reserved. F11站长开发者网 版权所有 | 苏ICP备2022031554号-1 | 51LA统计