Introducing spatie/ping and spatie/simple-tcp-client
We just tagged stable release for two new spatie packages: spatie/ping and spatie/simple-tcp-client. In this blogpost, I'd like to share why these were developed and how you can use them.
Why these packages were developed
Oh Dear is an all-in-one monitoring service that I've been running for almost 8 years now. Recently, I sent a survey to all users of Oh Dear to ask what they liked about the service and how we can improve it.
One of the bigger features a lot of our users asked for: ping and TCP monitoring. Currently, when Oh Dear checks the uptime of our site, it will send a simple GET request to see if it's online. This works well for regular sites, but you can't use this to check the uptime of servers that don't speak HTTP, like for instance a database, Redis or email server.
Ping monitoring entails running the unix ping
command that can send packets and get a response from a server. TCP monitoring entails opening a port on a server, and optionally sending a command through that port.
I'm currently developing ping / TCP monitoring, and expect to add this to Oh Dear in August / September.
While developing the feature, I was looking for good PHP packages to actually perform a unix ping and get structured results back, and to open a TCP connection. There weren't any that could do this in a simple and developer friendly way, so I decided to code them up myself.
Using spatie/ping
On most servers, the ping command is installed. This is its output. This output can be hard to parse programmatically.
The spatie/ping package provides a simple way to execute ping commands and parse the results into structured data. It wraps the system's ping command and returns detailed information about packet loss, response times, and connectivity status.
use Spatie\Ping\Ping; $result = (new Ping('8.8.8.8'))->run(); // returns an instance of \Spatie\Ping\PingResult // Basic status echo $result->isSuccess() ? 'Success' : 'Failed'; echo $result->hasError() ? "Error: {$result->error()?->value}" : 'No errors'; // Packet statistics echo "Packets transmitted: {$result->packetsTransmitted()}"; echo "Packets received: {$result->packetsReceived()}"; echo "Packet loss: {$result->packetLossPercentage()}%"; // Timing information echo "Min time: {$result->minimumTimeInMs()}ms"; echo "Max time: {$result->maximumTimeInMs()}ms"; echo "Average time: {$result->averageTimeInMs()}ms"; echo "Standard deviation: {$result->standardDeviationTimeInMs()}ms"; // Individual ping lines foreach ($result->lines() as $line) { echo "Response: {$line->getRawLine()} ({$line->getTimeInMs()}ms)"; }
Of course, you can configure how you want to run ping:
You can customize the ping behavior using constructor parameters:
$result = (new Ping( hostname: '8.8.8.8', timeoutInSeconds: 5, // seconds count: 3, // number of packets intervalInSeconds: 1.0, // seconds between packets packetSizeInBytes: 64, // how big the packet is we'll send to the server ttl: 64 // time to live (maximum number of hops) ))->run();
Using spatie/simple-tcp-client
The spatie/simple-tcp-client package provides a simple and elegant way to create TCP connections, send data, and receive responses. Perfect for interacting with TCP servers, testing network services, or building simple network clients.
use Spatie\SimpleTcpClient\TcpClient; $client = new TcpClient('smtp.gmail.com', 587); $client->connect(); $greeting = $client->receive(); echo $greeting; // 220 smtp.gmail.com ESMTP... $client->send("EHLO test.local\r\n"); $response = $client->receive(); echo $response; // 250-smtp.gmail.com capabilities... $client->close();
To develop this package, I used a bit of Claude Code to help me, as I didn't know anything about opening sockets with PHP. Claude generated the code for me, then I researched how it worked, and fine-tuned it myself.
In closing
Both spatie/ping and spatie/simple-tcp-client have some more options than mentioned here. Go to the readmes of the respective packages to learn more.
My guess is that not too many people will need these, but it still felt good open sourcing this code.
These packages will be used in the upcoming ping and TCP checks at Oh Dear. Our service is actually made up of multiple Laravel apps. By implementing this functionality as a package, I can just require it in all the apps that make up Oh Dear to have a consistent way of handling pings / TCP ports.
What are your thoughts on "Introducing spatie/ping and spatie/simple-tcp-client"?