Server-Sent Events in PHP: When the Server Knocks on the Browser Itself
\n\nHave you ever wondered how Twitter news feeds, exchange rates on the stock exchange, or messenger notifications work? That's right — data arrives on its own, without refreshing the page and without endless Ajax requests. Most developers immediately think of WebSockets, but there is another, much simpler and more elegant way — Server-Sent Events (SSE).
\n\nIn this article, we will break down how to implement Server-Sent Events in PHP from scratch. You will learn how to send data from the server in real time without overloading the infrastructure with complex libraries. No Node.js, no queues — just pure PHP and HTML5.
\n\nWhat are Server-Sent Events and Why Are They Needed?
\n\nSSE (Server-Sent Events) is an HTML5 standard that allows the server to send data to the client over a single HTTP connection. Unlike WebSockets, which work in both directions, SSE is a one-way channel: data flows only from the server to the client. But this is precisely its main advantage: the implementation is so simple that it requires neither additional libraries nor special servers.
\n\nWhere are server-sent events php used?
\n- \n
- News feeds and real-time notifications \n
- Server and log monitoring \n
- Currency exchange rates, stock quotes \n
- Progress indicators for long-running operations (file uploads, video processing) \n
- Chatbots and alert systems \n
Unlike classic polling (where the client pings the server every N seconds), SSE PHP creates a persistent connection that does not require repeated handshakes and headers. This saves traffic and CPU resources.
\n\nHow SSE Works: Protocol and Headers
\n\nSSE is based on a regular HTTP response with a special content type. The server sends data in a text format, using the keywords event, data, id, and retry. The client receives the stream and processes events as they arrive.
The basic protocol looks like this:
\nContent-Type: text/event-stream\nCache-Control: no-cache\nConnection: keep-alive\n\ndata: Hello, world\n\ndata: {"message": "This is JSON"}\n\nEach message starts with data:, followed by the text. If you need to send multiple lines, just write several data: lines in a row. An empty line \\n\\n signals the end of the message.
Writing Your First SSE Script in PHP
\n\nLet's create a simple script that will send the current time every 2 seconds. This is a classic example that immediately shows the magic of real-time PHP.
\n\nFile sse.php:
<?php\n// Disable output buffering\nob_implicit_flush(true);\nob_end_flush();\n\n// Set SSE headers\nheader('Content-Type: text/event-stream');\nheader('Cache-Control: no-cache');\nheader('Connection: keep-alive');\nheader('X-Accel-Buffering: no'); // For Nginx\n\nwhile (true) {\n // Prepare data\n $data = [\n 'time' => date('H:i:s'),\n 'timestamp' => time()\n ];\n \n // Send the event\n echo "data: " . json_encode($data) . "\\n\\n";\n \n // Check if the client has closed the connection\n if (connection_aborted()) {\n break;\n }\n \n // Pause for 2 seconds\n sleep(2);\n}\n?>\n\nNote: we use an infinite loop while(true), but we must check connection_aborted(). If the client closes the tab, the script will terminate without overloading the server.
Now let's write the client-side part in JavaScript:
\n<!DOCTYPE html>\n<html>\n<head>\n <title>SSE Demo PHP</title>\n</head>\n<body>\n <h2>Current time from the server:</h2