Download the PHP package hiblaphp/socket without Composer

On this page you can find all versions of the php package hiblaphp/socket. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package socket

Hibla Socket

Async, non-blocking TCP, TLS, and Unix domain socket library for PHP.

Part of the Hibla ecosystem. Built on top of hiblaphp/stream, hiblaphp/promise and hiblaphp/event-loop. All I/O is non-blocking and driven by the same loop that powers your fibers, timers, and promises.

Latest Release Tests Total Downloads


Contents

Getting started

Connections

Servers

Clients

Working with connections

Reference

Meta


Installation

This package is currently in beta. Before installing, ensure your composer.json allows beta releases:

Requirements:


Introduction

PHP's built-in socket functions (stream_socket_server(), stream_socket_client(), stream_socket_accept()) are synchronous and blocking. stream_socket_accept() stalls the entire PHP thread until a client connects. fread() on a socket blocks until data arrives. stream_socket_client() blocks during the TCP handshake. For a single connection in a simple script this is fine. The moment you need to handle multiple connections concurrently (a TCP server serving hundreds of clients, a client making parallel upstream requests, a proxy routing between two streams) blocking on any one operation freezes everything else. The event loop cannot fire timers, cannot resume Fibers, cannot read from other sockets while a blocking call is in progress.

The solution is to hand all socket I/O to the event loop entirely. Instead of calling stream_socket_accept() and waiting, you register a read watcher on the server socket and supply a callback. Instead of calling stream_socket_client() and blocking for the handshake, you open the socket in STREAM_CLIENT_ASYNC_CONNECT mode and register a write watcher. The event loop fires the callback the instant the OS confirms the connection is established. All reads and writes go through non-blocking streams backed by hiblaphp/stream watchers, so the event loop continues driving all other activity while I/O is in flight.

hiblaphp/socket is that abstraction. It provides:

Every established connection (server-side or client-side) is a ConnectionInterface backed by a hiblaphp/stream DuplexResourceStream. Data arrives as data events. Writes are buffered and drained asynchronously. Backpressure is tracked automatically via write()'s return value and the drain event. Connections integrate directly with hiblaphp/stream's pipe() so you can wire a file stream to a socket, or two sockets to each other, with one line and no manual flow control.

The library supports two coding styles throughout. Promise chains give you maximum throughput and zero Fiber overhead. This is the right choice for performance-critical paths where you are establishing thousands of connections per second. Optionally, await() from hiblaphp/async gives you sequential-looking code that is easier to read and reason about. This is the right choice for application-level logic where the overhead of Fiber suspension is invisible. Both styles compose freely: you can mix them in the same codebase, the same function, or the same Promise::all() call.


Quick Start

Echo server

TCP client


Two Styles: Promise Chains vs Await

Every connector method returns a PromiseInterface. You can consume it using raw promise chains or using await() from hiblaphp/async. Both styles are fully supported. Choose based on context.

await() suspends the current Fiber and resumes it when the promise settles, letting you write sequential-looking code without blocking the event loop. Promise chains are better when you need fine-grained control over branching, when you are not inside a Fiber context, or when you want to fire multiple connections concurrently without waiting on each one.

For performance-critical code or high-throughput scenarios (a proxy handling thousands of simultaneous connections, a load balancer, or any path where you are establishing connections in a tight loop) prefer pure promise chains over await(). Fiber suspension and resumption carries a small but measurable overhead per operation. At low concurrency this is invisible; at high concurrency it accumulates. If you are benchmarking or squeezing every last RPS, remove await() from the hot path and use .then() chains instead.

Connecting — promise chain style

Connecting — await style

Concurrent connections — promise chain style

Promise chains are the natural fit when firing multiple connections at once. Promise::all() runs them concurrently and resolves when every connection settles:

Concurrent connections — await style

TLS — promise chain style

TLS — await style


Connection Events

All established connections (whether from a server's connection event or a connector's resolved promise) implement ConnectionInterface and expose the same event API. Understanding these events before working with servers and clients makes every example in this document easier to follow.

Event reference

Event Arguments When it fires
data string $chunk A chunk of data arrives from the remote end
end — The remote end half-closes; no more data events will follow
drain — The write buffer drops below the soft limit; safe to write again
close — The connection is fully closed and the resource is freed
error \Throwable $e A stream error occurred; the connection closes immediately after

Ordering guarantees

Always attach an error listener on every connection. An unhandled error event on an EventEmitter propagates and may terminate your process.

Connection lifecycle

Attaching listeners

Promise chain style:

Await style:


Servers

SocketServer

SocketServer is the recommended entry point for most use cases. It inspects the URI scheme and instantiates the appropriate server (TcpServer, SecureServer, or UnixServer) automatically.

The $context array accepts three top-level keys (tcp, tls, and unix) each containing standard PHP stream context options for that transport:

All server types emit the same events:

Event Arguments When
connection ConnectionInterface $connection A new client connects
error \Throwable $error A non-fatal error occurs (e.g. accept failure)

TcpServer

Low-level TCP server. Binds to an IP and port.

Context options: any socket stream context option is accepted:


SecureServer

Wraps a TcpServer and performs the TLS handshake on every incoming connection before emitting it. Connections are only emitted after encryption is fully established.

Failed TLS handshakes emit an error event on the server and close the connection. They do not crash the server.


UnixServer

Listens on a Unix domain socket path.

The socket file is created on construction and removed automatically on close(). If the path already exists and is actively in use, AddressInUseException is thrown. A stale socket file (no listener) is removed and replaced automatically.


FdServer

Inherits a listening socket from a parent process via a file descriptor number. Useful for socket-activated services (systemd) or zero-downtime restarts.


LimitingServer

Decorates any ServerInterface to enforce a maximum number of concurrent connections.

Two modes when the limit is reached:

Pause mode provides true backpressure. The kernel's accept queue backs up instead of dropping connections. Reject mode is better when you want to send an explicit error response to the client before closing.


Clients

Connector

Connector is the recommended entry point for client connections. It handles DNS resolution, Happy Eyeballs dual-stack racing, TLS, Unix sockets, and timeouts behind a single connect() call.

Configuration options:


TcpConnector

Establishes a raw non-blocking TCP connection to an IP address. Does not perform DNS resolution. Pass a resolved IP.


SecureConnector

Wraps a TcpConnector (or any ConnectorInterface) and performs a TLS handshake after the transport is established.


UnixConnector

Connects to a Unix domain socket. The connection is established synchronously. By the time connect() returns a promise, the connection is already made and the promise is already resolved.


TimeoutConnector

Decorates any ConnectorInterface and rejects the promise with TimeoutException if the connection is not established within the given number of seconds. The timeout covers the entire connection process including DNS and TLS.


FixedUriConnector

Always connects to a pre-configured URI regardless of the URI passed to connect(). Useful for proxies, tunnels, and test mocks.


DNS Resolution

Connector handles DNS automatically. Under the hood it uses DnsConnector (single-stack) or HappyEyeBallsConnector (dual-stack, default).

If you need manual DNS resolution, inject a custom ResolverInterface:

To bypass DNS entirely (IP-only environments or when you resolve yourself):


Happy Eyeballs

When happy_eyeballs is enabled (the default), Connector implements RFC 8305:


Working with Connections

Reading and writing


Backpressure

write() returns false when the write buffer is full. Stop writing and wait for the drain event before continuing.

Promise chain style:

Await style:

If you are piping a Hibla stream into a connection, backpressure is handled automatically with no manual pause()/resume() needed:


Cancellation

Every connect() call returns a PromiseInterface. You can cancel an in-flight connection attempt by calling cancel() on the returned promise. Cancellation immediately aborts the underlying operation. DNS lookups, TCP handshakes, and TLS negotiations are all torn down cleanly with no dangling file descriptors or event loop watchers left behind.

Cancellation in Hibla is a distinct state from rejection. Calling cancel() on a promise does not trigger any registered then() or catch() handlers. The promise silently transitions to the cancelled state and all pending callbacks are cleared. Use onCancel() on the promise if you need to react to cancellation in a promise chain, or use await() with a CancellationToken, which throws CancelledException that you can catch with a normal try/catch.

Manual cancellation

In a pure promise chain there is no await(), so cancellation is silent: then() and catch() never fire. Register an onCancel() handler before cancelling if you need to react:

Timeouts are rejections, not cancellations

TimeoutConnector behaves differently from manually calling cancel(). When the timeout fires, it rejects the outer promise with a TimeoutException. This is a rejection and does trigger registered catch() handlers. Internally it cancels the pending connection, but the promise your code receives is rejected, not cancelled:

Structured cancellation with CancellationToken

For coordinating cancellation across multiple connections or operations from a single control point, use CancellationTokenSource from hiblaphp/cancellation. The source owns the cancel signal. You pass the readonly $token into operations and call cancel() on the source when you want everything to stop.

Single connection — await style

When using await($promise, $token), the token automatically tracks the promise with no manual track() needed. If the token is cancelled while await() is suspended, CancelledException is thrown:

Single connection — promise chain style

In a promise chain you must call $token->track() manually. Since cancellation is not rejection, catch() does not fire. Use onCancel() to react:

Multiple concurrent connections

One token cancels all tracked connections at once regardless of which phase each is in (DNS, TCP handshake, or TLS):

Combining user abort and timeout

createLinkedTokenSource() creates a token that cancels when any of the linked tokens fires. This is the standard way to combine a user-initiated abort with a hard deadline:

Optional token with CancellationToken::none()

If you are writing a function that should optionally support cancellation, use CancellationToken::none() as the default. All token methods work correctly on it without any null checks. track() is a safe no-op and throwIfCancelled() never throws:

Cancellation support by connector

Not every connector supports cancellation. The table below documents which connectors respond to cancel() and what happens when you call it.

Connector Cancellable What cancellation does
TcpConnector ✅ Removes the write watcher and closes the socket immediately
SecureConnector ✅ Cancels the pending TCP connection or TLS handshake, whichever is in flight
DnsConnector ✅ Cancels the DNS lookup if still resolving, or the connection attempt if DNS already completed
HappyEyeBallsConnector ✅ Cancels all pending resolver promises, connection attempts, and clears all internal timers
TimeoutConnector ✅ Cancels the timeout timer and propagates cancellation to the underlying connector
FixedUriConnector ✅ Delegates to the underlying connector and inherits its cancellation behaviour
Connector (facade) ✅ Delegates to whichever connector handles the URI scheme
UnixConnector ❌ Not cancellable — see note below

UnixConnector is not cancellable. Unix domain socket connections are established synchronously via a single stream_socket_client() call. By the time connect() returns a promise, the connection is already established and the promise is already resolved. There is nothing in flight to cancel. Calling cancel() on the returned promise is a no-op. Passing a CancellationToken to await() with a UnixConnector promise is equally a no-op. The promise is already settled before the token has a chance to fire.

If you need to enforce a time limit on a Unix socket connection, wrap it in a TimeoutConnector. The timeout fires as a rejection (not a cancellation) so catch() handlers fire normally:


Mid-flight TLS upgrade

Useful for protocols that start in plaintext and upgrade to TLS (MySQL, SMTP STARTTLS, PostgreSQL).

Important: Use once() instead of on() for the plain negotiation phase. enableEncryption() upgrades the underlying stream in place but does not remove listeners you registered before the upgrade. If you use on() for the plain phase, that listener stays attached and will fire again for every subsequent chunk, including data that arrives over the secure channel after the upgrade. once() removes itself automatically after the first call, so secure data only reaches the listeners you register after the upgrade completes.

Server side — promise chain style:

Server side — await style:

Client side — promise chain style:

Client side — await style:


Address inspection


Interface summary

Interface Implemented by
ServerInterface TcpServer, UnixServer, SecureServer, FdServer, SocketServer, LimitingServer
ConnectorInterface TcpConnector, UnixConnector, SecureConnector, DnsConnector, HappyEyeBallsConnector, TimeoutConnector, FixedUriConnector, Connector
ConnectionInterface Connection

Type-hint against the interfaces rather than concrete classes:


Exception reference

All exceptions extend Hibla\Socket\Exceptions\SocketException which extends \RuntimeException.

Exception When it is thrown
ConnectionFailedException TCP handshake failed, DNS lookup failed, or connection was refused
TimeoutException Connection attempt exceeded the configured timeout (extends ConnectionFailedException)
EncryptionFailedException TLS handshake failed or connection was lost during handshake
InvalidUriException Malformed or unsupported URI passed to a connector or server
BindFailedException Server failed to bind to the given address (port in use, bad path, invalid FD)
AddressInUseException Unix socket path is already actively in use (extends BindFailedException)
AcceptFailedException stream_socket_accept() failed on an otherwise healthy server

Development


Credits


License

MIT License. See LICENSE for more information.


All versions of socket with dependencies

PHP Build Version
Package Version
Requires php Version ^8.4
evenement/evenement Version ^3.0
hiblaphp/event-loop Version ^1.0
hiblaphp/stream Version ^1.0
hiblaphp/promise Version ^1.0
hiblaphp/dns Version ^1.0
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package hiblaphp/socket contains the following files

Loading the files please wait ...