HomePHP Page 4 - An Introduction to Sockets in PHP
Reusing the TCP server: defining the "createSocketServer()" function and "SocketServer" class - PHP
Working with low-level sockets can be a painful task in PHP. Fortunately, PHP offers a nice library of socket handling functions to make your life easier. If you do a lot of network programming in PHP, you will want to check out this three-part series, which starts with the basics and takes you through more advanced approaches. This article is the first one in the series.
As I said in the previous section, it'd be really handy to encapsulate the full code for creating the sample TCP server into one single function. The function would perform basically the same task, but have the advantage of making the code much more compact and reusable. Bearing in mind this concept, here's the definition for the corresponding "createSocketServer()" function:
function createSocketServer($host='127.0.0.1',$port=1234){ if(!preg_match("/^d{1,3}.d{1,3}.d{1,3}.d{1,3} $/",$host)){ trigger_error('Invalid IP address format.',E_USER_ERROR); } if(!is_int($port)||$port<1||$port>65535){ trigger_error('Invalid TCP port number.',E_USER_ERROR); } set_time_limit(0); // create low level socket if(!$socket=socket_create(AF_INET,SOCK_STREAM,0)){ trigger_error('Error creating new socket.',E_USER_ERROR); } // bind socket to TCP port if(!socket_bind($socket,$host,$port)){ trigger_error('Error binding socket to TCP port.',E_USER_ERROR); } // begin listening connections if(!socket_listen($socket)){ trigger_error('Error listening socket connections.',E_USER_ERROR); } // create communication socket if(!$comSocket=socket_accept($socket)){ trigger_error('Error creating communication socket.',E_USER_ERROR); } // read socket input $socketInput=socket_read($comSocket,1024); // convert to uppercase socket input $socketOutput=strtoupper(trim($socketInput))."n"; // write data back to socket server if(!socket_write($comSocket,$socketOutput,strlen ($socketOutput))){ trigger_error('Error writing socket output',E_USER_ERROR); } // close sockets socket_close($comSocket); socket_close($socket); }
As shown above, I hid all the complexities of creating the socket server, as well as reading, processing and returning client data in just one function, which I called "createSocketServer." This function does basically the same thing as the previous script, and introduces some additional checking code, in order to make sure that the two incoming arguments, that is the IP address and the TCP port respectively, have a valid format.
Now, creating the previous TCP server could be reduced to a process as simple as this:
// call 'createSocketServer()' function createSocketServer();
I told you it was simple! Again, remember first to save this function to a file and next run it from the PHP command line (also, it's possible to connect to the TCP server by using a Telnet client), in order to get things working appropriately.
Now that you know how the "createSocketServer()" function works, please have a look at the following PHP snippet, which encapsulates all the source code required for building the prior TCP server in one class:
class SocketServer{ var $host; var $port; function SocketServer($host='127.0.0.1',$port=1234){ if(!preg_match("/^d{1,3}.d{1,3}.d{1,3}.d{1,3} $/",$host)){ trigger_error('Invalid IP address format.',E_USER_ERROR); } if(!is_int($port)||$port<1||$port>65535){ trigger_error('Invalid TCP port number.',E_USER_ERROR); } $this->host=$host; $this->port=$port; $this->connect(); } function connect(){ set_time_limit(0); // create low level socket if(!$socket=socket_create(AF_INET,SOCK_STREAM,0)){ trigger_error('Error creating new socket.',E_USER_ERROR); } // bind socket to TCP port if(!socket_bind($socket,$this->host,$this->port)){ trigger_error('Error binding socket to TCP port.',E_USER_ERROR); } // begin listening connections if(!socket_listen($socket)){ trigger_error('Error listening socket connections.',E_USER_ERROR); } // create communication socket if(!$comSocket=socket_accept($socket)){ trigger_error('Error creating communication socket.',E_USER_ERROR); } // read socket input $socketInput=socket_read($comSocket,1024); // convert to uppercase socket input $socketOutput=strtoupper(trim($socketInput))."n"; // write data back to socket server if(!socket_write($comSocket,$socketOutput,strlen ($socketOutput))){ trigger_error('Error writing socket output',E_USER_ERROR); } // close sockets socket_close($comSocket); socket_close($socket); } }
In this case, I turned the "createSocketServer()" function into a fully working PHP class, thus if you feel inclined to work with object-oriented applications, this class could be quite appealing to you.
After building the "SocketServer" class, creating and using the prior TCP server can be reduced to the following two-liner:
// instantiate new 'SocketServer' object $socket=&new SocketServer();
That's it. In this article I've shown you different flavors of the same TCP server, according to your programming needs, so I guess there's enough code to provide you with long hours of fun!
To wrap up
Over this first part of the series, you hopefully learned the basics of how to create sockets in PHP, as well as read, process and write socket data through an instructive example, aimed at building a simple TCP server. However, there's still a huge area to be explored. Bearing this in mind, in the next article, I'll show you how to use low-level sockets, in order to build a "smarter" and more complex TCP server. You won't want to miss it!