[doc-en] master: socket_select(): document key preservation, and correct both select pages (#5829)
| From: | Louis-Arnaud via GitHub | Date: | Thu, 03 Sep 2026 11:57:00 +0000 |
| Subject: | [doc-en] master: socket_select(): document key preservation, and correct both select pages (#5829) | ||
| Groups: | php.doc.cvs | ||
| Request: | Send a blank email to doc-cvs+get-23710@lists.php.net to get a copy of this message | ||
Author: Louis-Arnaud (lacatoire)
Committer: GitHub (web-flow)
Pusher: lacatoire
Date: 2026-09-03T13:56:57+02:00
Commit: https://github.com/php/doc-en/commit/3e6082f609ead63cfa7b33a06d8e0c723d51bc65
Raw diff: https://github.com/php/doc-en/commit/3e6082f609ead63cfa7b33a06d8e0c723d51bc65.diff
socket_select(): document key preservation, and correct both select pages (#5829)
* socket_select(): say that the array keys are preserved
The page already warns that the arrays are modified on exit, but not that
an entry that stays keeps the key it came in with, which is what callers
need in order to map a ready socket back to whatever it belongs to.
stream_select() documents it; php_sock_array_from_fd_set() reinserts each
surviving entry under its original key, integer or string, so the two
functions agree.
Fixes: #5787
* socket_select(): fix the surrounding page while we are here
The page said the arrays could be left out. They cannot: the function
takes at least four arguments, an uninteresting one has to be an empty
array or null, and all three empty raises a ValueError. The microseconds
entry was an empty paragraph, and the notes carried a sentence that never
parsed ("If you read/write to a socket returns in the arrays").
Also stream_select() in seealso, since the two functions are each other's
counterpart, and the usual typos: happens.On, zero , causing, Due a
limitation, socket_select return.
* stream_select(): it is not equivalent to socket_select()
The page claimed the two functions operate identically apart from what
they act on. They do not. A negative timeout is a ValueError here and a
warning plus false there, an invalid element is skipped here and a
TypeError there, and microseconds is nullable only here.
The larger difference had no mention anywhere: when a stream already has
buffered data on the PHP side, select() is never called, and the write
and except arrays come back empty without having been looked at. A
caller watching for writability silently gets nothing.
Also socket_select() in seealso, and the same unparseable sentence about
partial reads that the socket_select() page carries.
Changed paths:
M reference/sockets/functions/socket-select.xml
M reference/stream/functions/stream-select.xml
Diff:
diff --git a/reference/sockets/functions/socket-select.xml
b/reference/sockets/functions/socket-select.xml
index 6ce55910d45a..67c07bb30283 100644
--- a/reference/sockets/functions/socket-select.xml
+++ b/reference/sockets/functions/socket-select.xml
@@ -61,43 +61,45 @@
<varlistentry>
<term><parameter>seconds</parameter></term>
<listitem>
- <para>
+ <simpara>
The <parameter>seconds</parameter> and
<parameter>microseconds</parameter>
together form the <literal>timeout</literal> parameter. The
<literal>timeout</literal> is an upper bound on the amount of time
- elapsed before <function>socket_select</function> return.
- <parameter>seconds</parameter> may be zero , causing
+ elapsed before <function>socket_select</function> returns.
+ <parameter>seconds</parameter> may be zero, causing
<function>socket_select</function> to return immediately. This is useful
for polling. If <parameter>seconds</parameter> is &null; (no timeout),
<function>socket_select</function> can block indefinitely.
- </para>
+ </simpara>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>microseconds</parameter></term>
<listitem>
- <para>
- </para>
+ <simpara>
+ See <parameter>seconds</parameter> description.
+ </simpara>
</listitem>
</varlistentry>
</variablelist>
</para>
<warning>
- <para>
+ <simpara>
On exit, the arrays are modified to indicate which socket
actually changed status.
- </para>
+ The original keys of the &array;s are preserved.
+ </simpara>
</warning>
- <para>
- You do not need to pass every array to
- <function>socket_select</function>. You can leave it out and use an
- empty array or &null; instead. Also do not forget that those arrays are
- passed <emphasis>by reference</emphasis> and will be modified after
+ <simpara>
+ The three arrays all have to be passed, but an array that is of no
+ interest can be an empty &array; or &null;; at least one of them must be
+ a non-empty &array;. They are passed
+ <emphasis>by reference</emphasis> and are modified once
<function>socket_select</function> returns.
- </para>
+ </simpara>
<note>
<para>
- Due a limitation in the current Zend Engine it is not possible to pass a
+ Due to a limitation in the current Zend Engine it is not possible to pass a
constant modifier like &null; directly as a parameter to a function
which expects this parameter to be passed by reference. Instead use a
temporary variable or an expression with the leftmost member being a
@@ -119,13 +121,13 @@ socket_select($r, $w, $e, 0);
<refsect1 role="returnvalues">
&reftitle.returnvalues;
- <para>
+ <simpara>
On success <function>socket_select</function> returns the number of
sockets contained in the modified arrays, which may be zero if
- the timeout expires before anything interesting happens.On error &false;
+ the timeout expires before anything interesting happens. On error &false;
is returned. The error code can be retrieved with
<function>socket_last_error</function>.
- </para>
+ </simpara>
<note>
<para>
Be sure to use the <literal>===</literal> operator when checking for an
@@ -202,10 +204,9 @@ if ($num_changed_sockets === false) {
</listitem>
<listitem>
<simpara>
- If you read/write to a socket returns in the arrays be aware that
- they do not necessarily read/write the full amount of data you have
- requested. Be prepared to even only be able to read/write a single
- byte.
+ When reading from or writing to a socket returned in the arrays, be
+ aware that the full amount of data requested is not necessarily read
+ or written. Be prepared for as little as a single byte.
</simpara>
</listitem>
<listitem>
@@ -222,14 +223,13 @@ if ($num_changed_sockets === false) {
<refsect1 role="seealso">
&reftitle.seealso;
- <para>
- <simplelist>
- <member><function>socket_read</function></member>
- <member><function>socket_write</function></member>
- <member><function>socket_last_error</function></member>
- <member><function>socket_strerror</function></member>
- </simplelist>
- </para>
+ <simplelist>
+ <member><function>socket_read</function></member>
+ <member><function>socket_write</function></member>
+ <member><function>socket_last_error</function></member>
+ <member><function>socket_strerror</function></member>
+ <member><function>stream_select</function></member>
+ </simplelist>
</refsect1>
</refentry>
diff --git a/reference/stream/functions/stream-select.xml
b/reference/stream/functions/stream-select.xml
index ebdac059c391..6ef1a7914e8a 100644
--- a/reference/stream/functions/stream-select.xml
+++ b/reference/stream/functions/stream-select.xml
@@ -16,11 +16,14 @@
<methodparam><type
class="union"><type>int</type><type>null</type></type><parameter>seconds</parameter></methodparam>
<methodparam choice="opt"><type
class="union"><type>int</type><type>null</type></type><parameter>microseconds</parameter><initializer>&null;</initializer></methodparam>
</methodsynopsis>
- <para>
- The <function>stream_select</function> function accepts arrays of streams and
- waits for them to change status. Its operation is equivalent to that of
- the <function>socket_select</function> function except in that it acts on streams.
- </para>
+ <simpara>
+ The <function>stream_select</function> function accepts arrays of streams
+ and waits for them to change status. It is the stream counterpart of
+ <function>socket_select</function>, but the two do not behave alike in
+ every respect: they report invalid arguments differently, and
+ <function>stream_select</function> can return without consulting the
+ operating system at all, as described in the notes below.
+ </simpara>
</refsect1>
<refsect1 role="parameters">
@@ -219,18 +222,27 @@ if (false === stream_select($r, $w, $e, 0)) {
</para>
</note>
<note>
- <para>
- If you read/write to a stream returned in the arrays be aware that
- they do not necessarily read/write the full amount of data you have
- requested. Be prepared to even only be able to read/write a single
- byte.
- </para>
+ <simpara>
+ When reading from or writing to a stream returned in the arrays, be aware
+ that the full amount of data requested is not necessarily read or
+ written. Be prepared for as little as a single byte.
+ </simpara>
</note>
<note>
- <para>
+ <simpara>
Some streams (like <literal>zlib</literal>) cannot be selected by this
function.
- </para>
+ </simpara>
+ </note>
+ <note>
+ <simpara>
+ A stream that already holds buffered data on the PHP side is reported as
+ ready without the underlying <literal>select()</literal> call being made.
+ When that happens the <parameter>write</parameter> and
+ <parameter>except</parameter> arrays are emptied without having been
+ examined, so a stream that was ready for writing goes unreported and the
+ return value counts the readable streams only.
+ </simpara>
</note>
<note>
<title>Windows compatibility</title>
@@ -250,6 +262,7 @@ if (false === stream_select($r, $w, $e, 0)) {
&reftitle.seealso;
<simplelist>
<member><function>stream_set_blocking</function></member>
+ <member><function>socket_select</function></member>
</simplelist>
</refsect1>
</refentry>