PHP 8.0: Sockets extension resources (Socket and AddressInfo) are class objects

Version8.0
TypeChange

In PHP 8.0 and later, all functions from Sockets extension return/accept objects of type \Socket and \AddressInfo class instead of resource of type Socket and AddressInfo.

This is similar to Curl extension using \CurlHandle objects as opposed to resource in PHP 8.0, and GD extension using \GdImage objects as opposed to gd resources.

Note that this only applies to socket_*() functions from ext/sockets. stream_socket_* functions (which return stream resources) are not affected.

\Socket class

final class Socket{
}

\Socket class objects replace return values of functions that formerly returned a resource of type Socket:

  • socket_accept()
  • socket_addrinfo_bind()
  • socket_addrinfo_connect()
  • socket_create()
  • socket_create_listen()
  • socket_import_stream()
  • socket_wsaprotocol_info_import()

Socket resources can be closed with the socket_close() function, which is still necessary in PHP 8.0 as well to promptly close an open socket.

\AddressInfo class

final class AddressInfo {
}

An array of \AddressInfo class objects will be returned by socket_addrinfo_lookup() function, which formerly returned an array of AddressInfo resources.

\Socket and \AddressInfo class semantics

  • Both classes are declared in the global namespace.
  • Declared final.
  • Has no methods.
  • Cannot be instantiated with new \Socket() and new AddressInfo().
  • Cannot be serialized.
  • Cannot be cloned.

Attempting to instantiate a \Socket object will throw a fatal error:

PHP Error:  Cannot directly construct Socket, use socket_create() instead in ... on line ...

socket_*() parameters and return values

All functions from Sockets extension will return/accept the new \Socket and \AddressInfo class objects.

is_resource() calls

All functions that create resources/class objects from the Sockets extension return false if the operation was unsuccessful.
Although not necessary, using is_resource() on the return value of such functions is quite common.

If you are calling is_resource, you will now need to account for the \Socket object return type too.

- if (is_resource($socket)) {
+ if (is_resource($socket) || $socket instanceof \Socket) {

Note that in PHP 7.2 and older, instanceOf operator requires an object. If you need to make your code function across PHP versions older than 7.3 through PHP 8.0, you will need an additional is_object() check:

- if (is_resource($socket)) {
+ if (is_resource($socket) || (is_object($socket) && $socket instanceof \Socket)) {

It is also completely valid to check the return value of functions that return resources to check the return value for false.

- if (is_resource($socket)) {
+ if ($socket !== false) {

Backwards Compatibility Impact

Socket extensions resource to object transformation is quite seamless. Unless you have an is_resource() call that checks a passed/return value, it will not require any changes in PHP 8.0.


Implementation