How is a WebSocket handshake implemented in PHP?

I am trying to write a piece of code which will generate the Sec-WebSocket-Accept value for a web socket connection. What I gather from resources online (i.e. MDN) is that you:

  1. Concatenate the string that the client sent you in Sec-WebSocket-Key onto the GUID (258EAFA5-E914-47DA-95CA-C5AB0DC85B11);

  2. Take the SHA-1 hash of the result of this concatenation;

  3. Convert the result of that to base 64.

So, if I understand this correctly, the corresponding PHP code would be:


However, this is not correct. It does not match the example shown on MDN (i.e. on MDN a value of dGhlIHNhbXBsZSBub25jZQ== for the WebSocket key should return s3pPLMBiTxaQ9kYGzzhZRbK+xOo=, but using the PHP code that I have written, it returns YjM3YTRmMmNjMDYyNGYxNjkwZjY0NjA2Y2YzODU5NDViMmJlYzRlYQ==).

What have I done incorrectly here?

The sha1() function accepts an optional second boolean parameter which makes it return the raw SHA-1 digest in 20-character binary form rather than 40-character hexadecimal form (see PHP Manual).

The WebSocket handshake requires the raw binary format. Thus, you need to add the second parameter to the sha1() function.