|  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #80723 Different sockets compare as equal (regression in 8.0)
Submitted: 2021-02-08 02:44 UTC Modified: 2021-02-16 11:36 UTC
From: bugs-a17 at moonlit-rail dot com Assigned: nikic (profile)
Status: Closed Package: Sockets related
PHP Version: 8.0.2 OS: Linux
Private report: No CVE-ID: None
 [2021-02-08 02:44 UTC] bugs-a17 at moonlit-rail dot com
In PHP 8.0, two different sockets compare as equal.
This is a regression versus PHP 7.x.

I use PHP for writing internet servers, and upgrading to 8.0 sees most of them failing.  Simple constructs such as, $socknum = array_search($sock, $sockets)
no longer function as they intuitively ought to.

As an aside, it used to be convenient to do, $array[(int)$socket] = $socket;
But in 8.0, (int) $socket bombs, and var_export($socket, true) returns the same value regardless of what's in the socket.

Test script:

$socket_1 = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
$socket_2 = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
$vector   = array(1 => $socket_1,
                  2 => $socket_2);
$IDX_1    = array_search($socket_1, $vector);
$IDX_2    = array_search($socket_2, $vector);
$V        = substr(PHP_VERSION, 0, 3);

echo "In PHP {$V}:\n".
     "\tSocket 1 was found at array index {$IDX_1}, and\n".
     "\tSocket 2 was found at array index {$IDX_2}.\n";


Expected result:
~$ /tmp/socket-compare-test.php 
In PHP 7.3:
        Socket 1 was found at array index 1, and
        Socket 2 was found at array index 2.

Actual result:
~$ /tmp/socket-compare-test.php 
In PHP 8.0:
        Socket 1 was found at array index 1, and
        Socket 2 was found at array index 1.


Add a Patch

Pull Requests

Add a Pull Request


AllCommentsChangesGit/SVN commitsRelated reports
 [2021-02-08 02:57 UTC]
That probably needs to be investigated, but you may be able to use WeakMaps as a better holder for things like this:

which might need to be documented...
 [2021-02-08 06:24 UTC] bugs-a17 at moonlit-rail dot com
Thanks for the note about the weak-maps, looks quite useful for many of my use cases.

One workaround for this bug is to use === rather than == in the comparison.

As the sockets now create a Socket class, and each instance appears empty, that might explain why <empty> == <empty> returns true; clearly, the Socket object returned by create_socket() should be populated with socket information (or at least a pointer to a resource) to permit the comparison to have something to work with.
 [2021-02-16 11:26 UTC]
-Assigned To: +Assigned To: nikic
 [2021-02-16 11:34 UTC]
Automatic comment on behalf of
Log: Fixed bug #80723
 [2021-02-16 11:34 UTC]
-Status: Assigned +Status: Closed
 [2021-02-16 11:36 UTC]
The replacement for (int)$socket is spl_object_id($socket). Though we might want to add an overload for sockets in particular, as we did for curl handles.
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Mon Apr 22 13:01:30 2024 UTC