clue/socket-raw
, (*1)
Simple and lightweight OOP wrapper for PHP's low-level sockets extension (ext-sockets)., (*2)
PHP offers two networking APIs, the newer streams API and the older socket API.
While the former has been a huge step forward in generalizing various streaming resources,
it lacks some of the advanced features of the original and much more low-level socket API.
This lightweight library exposes this socket API in a modern way by providing a thin wrapper around the underlying API., (*3)
-
Full socket API -
It exposes the whole socket API through a sane object-oriented interface.
Provides convenience methods for common operations as well as exposing all underlying methods and options.
-
Fluent interface -
Uses a fluent interface so you can easily chain method calls.
Error conditions will be signalled using
Exception
s instead of relying on cumbersome return codes.
-
Lightweight, SOLID design -
Provides a thin abstraction that is just good enough
and does not get in your way.
This library is merely a very thin wrapper and has no other external dependencies.
-
Good test coverage -
Comes with an automated test suite and is regularly tested in the real world.
Table of contents, (*4)
Support us
We invest a lot of time developing, maintaining and updating our awesome
open-source projects. You can help us sustain this high-quality of our work by
becoming a sponsor on GitHub. Sponsors get
numerous benefits in return, see our sponsoring page
for details., (*5)
Let's take these projects to the next level together! đ, (*6)
Quickstart example
Once installed, you can use the following example to send and receive HTTP messages:, (*7)
$factory = new \Socket\Raw\Factory();
$socket = $factory->createClient('www.google.com:80');
echo 'Connected to ' . $socket->getPeerName() . PHP_EOL;
// send simple HTTP request to remote side
$socket->write("GET / HTTP/1.1\r\n\Host: www.google.com\r\n\r\n");
// receive and dump HTTP response
var_dump($socket->read(8192));
$socket->close();
See also the examples., (*8)
Usage
Factory
As shown in the quickstart example, this library uses a Factory
pattern
as a simple API to socket_create()
.
It provides simple access to creating TCP, UDP, UNIX, UDG and ICMP protocol sockets and supports both IPv4 and IPv6 addressing., (*9)
$factory = new \Socket\Raw\Factory();
createClient()
The createClient(string $address, null|float $timeout): Socket
method is
the most convenient method for creating connected client sockets
(similar to how fsockopen()
or
stream_socket_client()
work)., (*10)
// establish a TCP/IP stream connection socket to www.google.com on port 80
$socket = $factory->createClient('tcp://www.google.com:80');
// same as above, as scheme defaults to TCP
$socket = $factory->createClient('www.google.com:80');
// same as above, but wait no longer than 2.5s for connection
$socket = $factory->createClient('www.google.com:80', 2.5);
// create connectionless UDP/IP datagram socket connected to google's DNS
$socket = $factory->createClient('udp://8.8.8.8:53');
// establish TCP/IPv6 stream connection socket to localhost on port 1337
$socket = $factory->createClient('tcp://[::1]:1337');
// connect to local Unix stream socket path
$socket = $factory->createClient('unix:///tmp/daemon.sock');
// create Unix datagram socket
$socket = $factory->createClient('udg:///tmp/udg.socket');
// create a raw low-level ICMP socket (requires root!)
$socket = $factory->createClient('icmp://192.168.0.1');
createServer()
The createServer($address)
method can be used to create a server side (listening) socket bound to specific address/path
(similar to how stream_socket_server()
works).
It accepts the same addressing scheme as the createClient()
method., (*11)
// create a TCP/IP stream connection socket server on port 1337
$socket = $factory->createServer('tcp://localhost:1337');
// create a UDP/IPv6 datagram socket server on port 1337
$socket = $factory->createServer('udp://[::1]:1337');
create*()
Less commonly used, the Factory
provides access to creating (unconnected) sockets for various socket types:, (*12)
$socket = $factory->createTcp4();
$socket = $factory->createTcp6();
$socket = $factory->createUdp4();
$socket = $factory->createUdp6();
$socket = $factory->createUnix();
$socket = $factory->createUdg();
$socket = $factory->createIcmp4();
$socket = $factory->createIcmp6();
You can also create arbitrary socket protocol types through the underlying mechanism:, (*13)
$factory->create($family, $type, $protocol);
Socket
As discussed above, the Socket
class is merely an object-oriented wrapper around a socket resource. As such, it helps if you're familar with socket programming in general., (*14)
The recommended way to create a Socket
instance is via the above Factory
., (*15)
Methods
All low-level socket operations are available as methods on the Socket
class., (*16)
You can refer to PHP's fairly good socket API documentation or the docblock comments in the Socket
class to get you started., (*17)
Data I/O:
$socket->write('data');
$data = $socket->read(8192);
Unconnected I/O:
$socket->sendTo('data', $flags, $remote);
$data = $socket->rcvFrom(8192, $flags, $remote);
Non-blocking (async) I/O:
$socket->setBlocking(false);
$socket->selectRead();
$socket->selectWrite();
Connection handling:
$client = $socket->accept();
$socket->bind($address);
$socket->connect($address);
$socket->shutdown();
$socket->close();
Install
The recommended way to install this library is through Composer.
New to Composer?, (*18)
This project follows SemVer.
This will install the latest supported version:, (*19)
$ composer require clue/socket-raw:^1.6
See also the CHANGELOG for details about version upgrades., (*20)
This project aims to run on any platform and thus does not require any PHP
extensions besides ext-sockets
and supports running on legacy PHP 5.3 through
current PHP 8+.
It's highly recommended to use the latest supported PHP version for this project., (*21)
Tests
To run the test suite, you first need to clone this repo and then install all
dependencies through Composer:, (*22)
$ composer install
To run the test suite, go to the project root and run:, (*23)
$ vendor/bin/phpunit
Note that the test suite contains tests for ICMP sockets which require root
access on Unix/Linux systems. Therefor some tests will be skipped unless you run
the following command to execute the full test suite:, (*24)
$ sudo vendor/bin/phpunit
The test suite also contains a number of functional integration tests that rely
on a stable internet connection.
If you do not want to run these, they can simply be skipped like this:, (*25)
$ vendor/bin/phpunit --exclude-group internet
License
This project is released under the permissive MIT license., (*26)
Did you know that I offer custom development services and issuing invoices for
sponsorships of releases and for contributions? Contact me (@clue) for details., (*27)