Completing a Query Processor in PHP

Welcome to the third part of the series “Network Programming in PHP.” In three tutorials, this series explains the basics of network programming in PHP, by developing a query processor class in PHP 5, which uses some of the most popular PHP network functions, in order to implement the logic of its methods.

Introduction

If you’ve been reading the previous articles of the series, then you’ll probably know that using some networking PHP built-in functions is really an easy process, and admittedly presents some interesting points, particularly if you’re interested in swimming deeply in the waters of PHP networking programming.

With reference to exploring the numerous PHP functions included in its network library, in the second article I aggregated a few handy methods to the “QueryProcessor” class, in order to demonstrate how to use the “exec()” native PHP function for running some popular Windows network monitoring utilities. These include “ipconfig,” “netstat” and “ping” programs, as well as the “lookup” command, which can be quite useful for (among other things) retrieving the list of MX records that correspond to a specific Internet host.

However, as I said right at the end of the previous article, the “QueryProcessor” class isn’t complete yet, since I’d like to add to it even more methods, aimed at performing some handy tasks. These include scanning of specific TCP ports, searching and checking for different types of DNS records, and so forth.

Therefore, in this last article of the series, I’ll add some extra methods to the query processor class, which can be used for performing the networking operations that I mentioned before. Of course, I’ll implement within all the methods an easy-to-grasp programming logic, so you shouldn’t have any problems understanding how each method works.

Ready to start learning how to code the remaining methods of the query processor class? Let’s do it together!

{mospagebreak title=A brief look at the QueryProcessor class}

Naturally, before I continue adding more methods to the query processor class, it’s a good idea to recall how this class was defined. For this reason, below I listed the full source code of the class, as it was written during the previous tutorial:

class QueryProcessor{
    private $host;
    private $services=array
(‘http’,’https’,’ftp’,’telnet’,’imap’,’smtp’,’nicname’,
‘gopher’,’finger’,’pop3′,’www’);
    private $ports=array(21,23,25,43,70,79,80,110,143,443);
    public function __construct($host=’myhost.com’){
        $this->host=$host;
    }
    // get IP address
    public function getIp(){
        if(!$ip=gethostbyname($this->host)){
            throw new Exception(‘Error resolving host IP
address.’);
        }
        return $ip;
    }
    // get list of IP addresses
    public function getIpList(){
        if(!$ips=implode(‘ – ‘,gethostbynamel($this->host))){
            throw new Exception(‘Error getting list of IP
addresses for the provided hostname.’);
        }
        return $ips;
    }
    // get host name
    public function getHost(){
        if(!$host=gethostbyaddr($this->getIp())){
            throw new Exception(‘Error resolving host name.’);
        }
        return $host;
    }
    // get TCP ports of Internet services
    public function getServicePorts(){
        $output=’Retrieving services ports…Please wait.<br />';
        foreach($this->services as $service){
            if(!$port=getservbyname($service,’tcp’)){
                $output.=’Error retrieving port of service
‘.$service.'<br />';
            }
            else{
                $output.=’Service ‘.$service. ‘ runs on TCP
port :’. $port.'<br />';
            }
        }
        return $output;
    }
    // get Services by TCP ports
    public function getServiceNames(){
        $output=’Retrieving services names…Please wait.<br />';
        foreach($this->ports as $port){
            if(!$service=getservbyport($port,’tcp’)){
                $output.=’Error retrieving service name on port
‘.$port.'<br />';
            }
            else{
                $output.=’TCP Port ‘.$port. ‘ is used by
service :’. $service.'<br />';
            }
        }
        return $output;
    }
    // execute ‘ipconfig’ command on Windows systems
    public function IpConfig(){
        $output=’Running ipconfig command…Please wait.<br />';
        exec(‘ipconfig’,$lines);
        foreach($lines as $line){
            $output.=$line.'<br />';
        }
        return $output;
    }
    // execute ‘ping’ command on Windows systems
    public function Ping(){
        $output=’Running ping command…Please wait.<br />';
        exec(‘ping ‘.$this->host,$lines);
        foreach($lines as $line){
            $output.=$line.'<br />';
        }
        return $output;
    }
    // execute ‘netstat’ command on Windows systems
    public function Netstat(){
        $output=’Running netstat command…Please wait.<br />';
        exec(‘netstat’,$lines);
        foreach($lines as $line){
            $output.=$line.'<br />';
        }
        return $output;
    }
    // get MX records on Windows systems
    public function getMXRecordsWin(){
        $output=’Retrieving MX Records…please wait.<br />';
        exec(“nslookup -type=mx $this->host”,$mxhosts);
        foreach($mxhosts as $mxhost){
            $output.=$mxhost.'<br />';
        }
        return $output;
    }
}

Okay, that’s the complete definition for the “QueryProcessor” class. Now, it’s time to move on and continue adding more methods to the class. Go ahead and read the next section. 

{mospagebreak title=Expanding the functionality of the QueryProcessor class: defining the getMXRecords() and checkDNSRecords() methods}

I’m sure you’ll remember that in the second part of the series, I defined a class method called “getMXRecordsWin().” The functionality of this method was basically retrieving the list of MX records corresponding to an Internet host, in case you’re working with a Windows-based system. Now, I’ll show you the definition of a method that does essentially the same thing, but uses the “getmxrr()” PHP function, which as you know, isn’t available in Windows. The signature for this method is as follows:

// get MX records
public function getMXRecords(){
    if(getmxrr($this->host,$mxhosts)){
        throw new Exception(‘No MX Records were found.’);
    }
    $output=’Retrieving MX Records…please wait.<br />';
    foreach($mxhosts as $mxhost){
        $output.=$mxhost.'<br />';
    }
    return $output;
}

In this case, the above method tries to obtain the list of MX records that match the given host name (when applicable), and next loops over the resulting array. Finally the output is returned to calling code.

After defining the “getMXRecords()” method, have a look at this new one, tasked with checking whether there are records in the DNS for a specific Internet host:

// check for DNS records
public function checkDNSRecords($recType=’MX’){
    // allowed values for $recType
    $validRecTypes=array
(‘A’,’MX’,’NS’,’SOA’,’PTR’,’CNAME’,’AAAA’,’A6′,’SRV’,
‘NAPTR’,’ANY’);
    if(!in_array($recType,$validRecTypes)){
        throw new Exception(‘Invalid DNS record type.’);
    }
    if(!checkdnsrr($this->host,$recType)){
        throw new Exception(‘No ‘.$recType.’ records were
found.’);
    }
    return ‘DNS records where found.';
}

As you can see, the method listed above checks in the DNS to see whether there are records that match the given host name, by using the “checkdnsrr()” PHP native function. Also, the method verifies whether the type of record passed as argument is valid or not, and throws an exception if no records are found in the DNS.

In addition, since the “checkdnsrr()” function is not supported on Windows systems, I coded a new method that can be used with Windows machines, and performs the same operation that you saw before. This is how this method looks:

// check for DNS records on Windows systems
public function checkDNSRecordsWin($recType=’MX’){
    // allowed values for $recType
    $validRecTypes=array
(‘A’,’MX’,’NS’,’SOA’,’PTR’,’CNAME’,’AAAA’,’A6′,’SRV’,
‘NAPTR’,’ANY’);
    if(!in_array($recType,$validRecTypes)){
        throw new Exception(‘Invalid DNS record type.’);
    }
    exec(‘nslookup -type=’.$recType.’ ‘.$this->host,$result);
    foreach($result as $line){
        if(preg_match(“/^$this->host/”,$line)){
            return ‘DNS records were found.';
        }
    }
    throw new Exception(‘No ‘.$recType.’ records were found.’);
}

As I mentioned before, this method checks for the existence of records in the DNS for a specific Internet host, and can be run on Windows-based computers, so depending on the operating system you’re using, you can utilize this method or the previous one for performing a quick DNS search.

At this point, you have seen three new methods that demonstrate how to look for certain records in the DNS, in accordance with the operating system being used. However, there are still more methods to add to the “QueryProcessor” class, in order to get it completed. Therefore, the next section of this article will show you the definition of these additional methods, responsible for scanning TCP ports, running a basic “WHOIS” service and more. Thus, click on the link below and keep reading.

{mospagebreak title=Scanning TCP ports, running a WHOIS service and more: defining the scanPort() and getWhois() methods}

The last two methods of the “QueryProcessor” class tackle different tasks. The first one, “scanPort(),” not surprisingly checks whether a given TCP port is available for connections, and its source code is the following:

// scan TCP ports
public function scanPort($port=80){
    if(!is_int($port)||$port<1||$port>65535){
        throw new Exception(‘Invalid TCP port number.’);
    }
    $output=’Scanning port ‘.$port.’…please wait.<br />';
    if(!$fp=@fsockopen($this->host,$port,$errno,$errstr,30)){
        throw new Exception(‘Unable to open connection to port
‘.$port);
    }
    fclose($fp);
    return ‘Port ‘.$port.’ is open to connections.';
}

As shown above, the “scanPort()” method verifies whether or not a specific TCP port is open to connections by using the powerful “fsockopen()” PHP function. In this case, if the port in question isn’t available, a new exception is thrown. Otherwise, a string is returned, confirming that the connection has been successfully established.

Now that you know how the “scanPort()” method works, turn your attention to the last method of the class, called “getWhois(),” which implements a basic “WHOIS” service. Please take a look at its source code:

// get basic WHOIS info
public function getWhoIs(){
    $output=’Retrieving WHOIS information…please wait.<br />';
    if(!$fp=fsockopen(“whois.opensrs.net”,43,$errno, $errstr,30)){
        throw new Exception(‘Error opening socket connection to
WHOIS server.’);
    }
    sleep(2);
    fputs($fp,”$this->hostrn”);
    while(!feof($fp)){
        $output.=fread($fp,128).'<br />';
    }
    fclose($fp);
    return $output;
}

Surely, you’ll agree with me the above method is really easy to understand. What it does essentially is implement a basic WHOIS service, by opening a socket connection to the “whois.opensrc.net” WHOIS host. Of course, this is merely an example of how to build this kind of service, and should be used with caution and responsibility. Eventually, you may want to change the WHOIS server and use another one.

Similar to the previous methods that you learned, if the connection to the host is successfully established, the server response is returned to calling code, while if the connection fails, an exception is thrown. Simple, right?

At this stage, I think all the methods I coded earlier complete the “QueryProcessor” class. Now, it’s time to see the full source code for this class, after adding the additional methods I wrote before. Want to see the complete definition for the query processor? Go ahead and read the next few lines.

{mospagebreak title=Getting the class completed: listing the full source code of the QueryProcessor class}

As I said right at the end of the previous section, here is the complete definition for the “QueryProcessor” class:

class QueryProcessor{
    private $host;
    private $services=array(‘http’,’https’,’ftp’,’telnet’,’imap’,’smtp’,’nicname’,
‘gopher’,’finger’,’pop3′,’www’);
    private $ports=array(21,23,25,43,70,79,80,110,143,443);
    public function __construct($host=’myhost.com’){
        $this->host=$host;
    }
    // get IP address
    public function getIp(){
        if(!$ip=gethostbyname($this->host)){
            throw new Exception(‘Error resolving host IP
address.’);
        }
        return $ip;
    }
    // get list of IP addresses
    public function getIpList(){
        if(!$ips=implode(‘ – ‘,gethostbynamel($this->host))){
            throw new Exception(‘Error getting list of IP
addresses for the provided hostname.’);
        }
        return $ips;
    }
    // get host name
    public function getHost(){
        if(!$host=gethostbyaddr($this->getIp())){
            throw new Exception(‘Error resolving host name.’);
        }
        return $host;
    }
    // get TCP ports of Internet services
    public function getServicePorts(){
        $output=’Retrieving services ports…Please wait.<br />';
        foreach($this->services as $service){
            if(!$port=getservbyname($service,’tcp’)){
                $output.=’Error retrieving port of service
‘.$service.'<br />';
            }
            else{
                $output.=’Service ‘.$service. ‘ runs on TCP
port :’. $port.'<br />';
            }
        }
        return $output;
    }
    // get Services by TCP ports
    public function getServiceNames(){
        $output=’Retrieving services names…Please wait.<br />';
        foreach($this->ports as $port){
            if(!$service=getservbyport($port,’tcp’)){
                $output.=’Error retrieving service name on port
‘.$port.'<br />';
            }
            else{
                $output.=’TCP Port ‘.$port. ‘ is used by
service :’. $service.'<br />';
            }
        }
        return $output;
    }
    // execute ‘ipconfig’ command on Windows systems
    public function IpConfig(){
        $output=’Running ipconfig command…Please wait.<br />';
        exec(‘ipconfig’,$lines);
        foreach($lines as $line){
            $output.=$line.'<br />';
        }
        return $output;
    }
    // execute ‘ping’ command on Windows systems
    public function Ping(){
        $output=’Running ping command…Please wait.<br />';
        exec(‘ping ‘.$this->host,$lines);
        foreach($lines as $line){
            $output.=$line.'<br />';
        }
        return $output;
    }
    // execute ‘netstat’ command on Windows systems
    public function Netstat(){
        $output=’Running netstat command…Please wait.<br />';
        exec(‘netstat’,$lines);
        foreach($lines as $line){
            $output.=$line.'<br />';
        }
        return $output;
    }
    // get MX records on Windows systems
    public function getMXRecordsWin(){
        $output=’Retrieving MX Records…please wait.<br />';
        exec(“nslookup -type=mx $this->host”,$mxhosts);
        foreach($mxhosts as $mxhost){
            $output.=$mxhost.'<br />';
        }
        return $output;
    }
    // check for DNS records
    public function checkDNSRecords($recType=’MX’){
        // allowed values for $recType
        $validRecTypes=array
(‘A’,’MX’,’NS’,’SOA’,’PTR’,’CNAME’,’AAAA’,’A6′,’SRV’,
‘NAPTR’,’ANY’);
        if(!in_array($recType,$validRecTypes)){
            throw new Exception(‘Invalid DNS record type.’);
        }
        if(!checkdnsrr($this->host,$recType)){
            throw new Exception(‘No ‘.$recType.’ records were
found.’);
        }
        return ‘DNS records where found.';
    }
    // check for DNS records on Windows systems
    public function checkDNSRecordsWin($recType=’MX’){
        // allowed values for $recType
        $validRecTypes=array
(‘A’,’MX’,’NS’,’SOA’,’PTR’,’CNAME’,’AAAA’,’A6′,’SRV’,
‘NAPTR’,’ANY’);
        if(!in_array($recType,$validRecTypes)){
            throw new Exception(‘Invalid DNS record type.’);
        }
        exec(‘nslookup -type=’.$recType.’ ‘.$this->host,$result);
        foreach($result as $line){
            if(preg_match(“/^$this->host/”,$line)){
                return ‘DNS records were found.';
            }
        }
        throw new Exception(‘No ‘.$recType.’ records were
found.’);
    }
    // scan TCP ports
    public function scanPort($port=80){
        if(!is_int($port)||$port<1||$port>65535){
            throw new Exception(‘Invalid TCP port number.’);
        }
        $output=’Scanning port ‘.$port.’…please wait.<br />';
        if(!$fp=@fsockopen($this->host,$port,$errno,$errstr,30)){
            throw new Exception(‘Unable to open connection to
port ‘.$port);
        }
        fclose($fp);
        return ‘Port ‘.$port.’ is open to connections.';
    }
    // get basic WHOIS info
    public function getWhoIs(){
        $output=’Retrieving WHOIS information…please wait.<br />';
        if(!$fp=fsockopen(“whois.opensrs.net”,43,$errno, $errstr,30)){
            throw new Exception(‘Error opening socket connection
to WHOIS server.’);
        }
        sleep(2);
        fputs($fp,”$this->hostrn”);
        while(!feof($fp)){
            $output.=fread($fp,128).'<br />';
        }
        fclose($fp);
        return $output;
    }
} 

Right, I think that you now have a quite useful query processor class that can be utilized for performing some common networking operations in PHP. Also, in order to get things completed, below I coded an example that illustrates how to use some of the methods that I just added to the class:

// instantiate ‘QueryProcessor’ object
$queryProc=new QueryProcessor(‘google.com’);

// display DNS records
echo $queryProc->checkDNSRecords();
/* displays the following output
DNS records were found.
*/

// scan TCP ports
echo $queryProc->scanPort();
/* displays the following output
Port 80 is open to connections.
*/

Final thoughts

In this series, I introduced you to the exciting terrain of network programming in PHP by building a query processor class. I hope that each method I wrote here will serve as a clear example of how to use popular PHP networking functions, at least at a basic level.

Now that you know how to check TCP ports, check for DNS records, obtain IP addresses and so forth, go ahead and develop sophisticated PHP network applications. See you in the next PHP tutorial! 

[gp-comments width="770" linklove="off" ]

antalya escort bayan antalya escort bayan Antalya escort diyarbakir escort