Why do server-sent events initiate every 3 seconds?

The example on W3Schools is a bit of a bad example.

For most HTTP response/requests exchanges, the client makes an HTTP request to the server, the server sends back data and the exchange is complete.

For SSE (although it still uses the HTTP protocol) this works a bit different. Here the client makes a request to the server, the session remains open and the server can send data whenever it pleases. If the session is closed for whatever reason, the EventSource will try to reconnect and everything starts over.

The problem in your PHP script is that the script ends the request/response exchange after it finished the last line. This means that the connection is closed and so the EventSource will try to reconnect. (Adding an .onerror event will show that an error is raised after every message.)

As is defined in the specification:

A reconnection time, in milliseconds. This must initially be a user-agent-defined value, probably in the region of a few seconds.

This is why you receive updates every three seconds. Because that is what the user-agent-defined value is set to.

Just below that line you can also see:

Apart from url these are not currently exposed on the EventSource object.

This means that this value cannot currently be set from JavaScript.

It is possible though to set this value from your server by defining it in the retry field in the SSE message. Here you can define in miliseconds how long the user agent should wait before reconnecting to your server. If you want to set it to one second it should be:

$time = date('r');
// If the connection closes, retry in 1 second
echo "retry: 1000\n";
echo "data: The server time is: {$time}\n\n";
flush();

But of course it would be better to implement SSE properly without closing the connection after the first message.

A good explanation can be found on MDN. I recommend to use MDN over W3Schools in general. W3Schools is not the most liked resource here on Stack Overflow and this is a good example why.