PHP Networking

PHP has a great many tools for interacting with a network and also with the Internet. In this article we will look at some of those tools and functions to see how we can use them to make our scripts more useful in a network environment. This article is the first of two parts.

Accessing other websites

Accessing other sites with PHP is extremely easy. But why would you want to access another website? If you just want to get information from a website, for instance a website that has a weather report on a city that is of interest to you, then you can write a spider and get that information and more. I said accessing websites with PHP is easy because you access a website in pretty much the same way that you would access a text file on your hard drive, i.e. by using fopen().


fopen( http://localhost/websecure/ftp.php , “r”);


The fopen() function that we use to open files is also used to open web pages, because a web page is essentially a file on a server. fopen() has the following modes:



Mode

Meaning

r

Reading only, begins reading at the start of the file.

r+

Reading or writing, begins reading at the start of the file.

w

Writing only. Creates the file if it does not exist, and overwrites any existing content.

w+

Reading or writing. Creates the file if it does not exist, and overwrites any existing content (when writing).

a

Writing only. Creates the file if it does not exist, and appends the new data to the end of the file.

a+

Reading or writing. Creates the file if it does not exist, and overwrites any existing contents (when writing).

x

Writing only. Creates the file if it does not exist, but does nothing, issues a warning, if the file does exist.

x+

Reading or Writing. Creates the file if it does not exist, but do nothing, issues a warning, if the file does exist.

You will only be able to open a file for reading, unless the permissions are set otherwise. Also you will have to use a trailing slash after a directory because fopen does not support redirects. For example:


fopen(“ http://localhost/websecure/ftp.php /”, “r”);


the above example is fine, but the one below will fail:


fopen( http://localhost/websecure/ftp.php , “r”);


Once you’ve opened a file, you can pretty much treat it the same way you would any other file, using common functions such as file() or fgets() to place or retrieve the data.

An example in code might be something like this:


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />

<title>Untitled Document</title>

</head>


<body>

<form action="tester.php" method="get">

<input name="url" type="text" />

<input name="" type="button" />

</form>

</body>

</html>


And the processing code might look something like this:


<?

$url=$_POST['url'];

$fp=file($url);

$n=count($fp);

$r=rand(0,($n-1));

echo trim($fp[$r]);

echo $n;

?>


{mospagebreak title=DNS and PHP}

PHP provides a powerful set of functions for DNS name resolution. Though the functions that are provided by PHP are limited to DNS client functionality and no server related functions are available, this is adequate since most applications will only require a name resolution service.

Below is a list of some of the functions that are available in PHP (from the PHP manual):


gethostbyname()

string gethostbyname(string hostname)


This function takes a single argument, which is the hostname of a machine, and returns a string corresponding to the IP address:


<?php

$host = "localhost";

$ip = gethostbyname($host);


echo "The IP address of $host is $ip";

?>


This script displays the IP address of http://localhost as a dot-separated string of numbers. We need to obtain the IP address of a host before we can connect to it using the sockets API, as we shall soon see.


gethostbynamel()


array gethostbynamel(string hostname)


Machines running operating systems that support virtual IP addresses (that is, one network card can have multiple IP addresses) can have more than one IP address associated with them. In this case, gethostbynamel() works like gethostbyname() but returns the complete list of IP addresses associated with that hostname as an array:


<?php

$host= "localhost";

$ip= gethostbynamel($host);


echo("The IP addresses of $hostare:<br>n");

for ($i = 0; $i < count($ip); $i++) {

echo("$ip [i] <br>n");

}

?>


Assuming that web.local.com is a machine with multiple IP addresses, this script prints a list of all those addresses.

The other scenario where one DNS name maps onto multiple IP addresses is when certain DNS server implementations (such as BIND) support a feature known as DNS round robin. This is a rudimentary load-balancing mechanism where one DNS name maps to multiple machines (that is, IP addresses of multiple machines). The DNS queries are resolved by the server to each of these IP addresses using a round robin scheme, thereby distributing the request load between multiple machines. More information on BIND is available at http://www.isc.org/products/BIND/.


gethostbyaddr()

string gethostbyaddr(string ip_address)


This function does the reverse of gethostbyname() in that, given the IP address as an argument, it returns the host name corresponding to it:


<?php

$ip = "127.0.0.1";

$host= gethostbyaddr($ip);


echo("The host name corresponding to the IP

address $ip is $host");

?>


This script displays the hostname corresponding to the IP address 127.0.0.1, which is always the localhost machine, that is, the machine on which the script was run.

{mospagebreak title=DNS and PHP continued}

While each machine on the TCP/IP network must have at least one IP address, there is no requirement that it should have a DNS name. Thus it is entirely possible that a machine may have an IP address and no DNS entry; in which case the function returns the ip_address argument itself. In fact, if an error occurs, the return value of the function is the ip_address argument.


getprotobyname()


int getprotobyname(string name)


This function returns the protocol number associated with a TCP/IP protocol, which is a unique integer associated with the protocol name that is passed to it as an argument. The name-to-protocol mapping is stored in a text file, usually in /etc/protocols on UNIX-derived systems and %SystemRoot%System32driversetcprotocol on Microsoft Windows NT or Windows 2000.


getprotobynumber()

string getprotobynumber(int number)


This function has just the opposite functionality of the getprotobyname() function in that, given the protocol number as an argument, it displays the protocol name.


getservbyname()

int getservbyname(string service, string protocol)


We need to obtain the well-known port number at which a service is running before our client can connect to it. This function takes a service name, and the transport protocol, that is either TCP or UDP, and returns the port number associated with the service. On most UNIX machines the port number to service mapping is specified in the /etc/services file:


<?php

$protocol = "smtp";

$portNum = getservbyname($protocol, "tcp");


echo("The port number of the $protocol service is $portNum");

?>


This prints the port number of the Simple Mail Transfer Protocol as 25. On most UNIX machines the information mapping the protocol name with the protocol number is available in the /etc/protocol file.


getservbyport()

string getservbyport(int port, string protocol)


This function has just the opposite functionality of getservbyname(); it prints the service name associated with the port number argument. The protocol argument indicates the transport protocol (that is TCP or UDP) that the service is implemented over.


As we saw, the getprotobyname(), getprotobynumber(), getservbyname(), and getservbynumber() functions obtain their information from files on the local file system (on most platforms). Therefore, they are not really DNS functions, but we examine them in this context since they are essentially resolver functions.

{mospagebreak title=Getting information about a domain name}

When looking at a domain name as part of a email address or URL, you simply do not get enough information from it. You can even go so far as visiting that URL and you still will not have enough information about the ownership of that particular domain. Most of the kind of information that you would want will be located in a WHOIS database. These databases are maintained by registrars and can provide information about the owners of a particular domain. To get the information from these databases you need to run a whois query from a client application. PHP provides this kind of client application through the PEAR package.

PEAR has a class that enables you to query a whois database. This class is called Net_Whois. And is used like so:


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />

<title>Untitled Document</title>

</head>


<body>

<?

require_once "Net/Whois.php";

$server = "whois.networksolutions.com";

$query = "metroworks.com";

$whois = new Net_Whois;

$urlinfo = $whois->query($query, $server);

var_dump($urlinfo);

?>

</body>

</html>


First the code defines the server where the whois database is located:


$server = "whois.networksolutions.com";


Then it defines the name of the domain on which it wants to run a query:


$query = "metroworks.com";


Finally the query is run, after the Net_whois class is instantiated:


$whois = new Net_Whois;

$urlinfo = $whois->query($query, $server);


and the information from the query is shown:


var_dump($urlinfo);

The var_dump() function will show the entire contents of the $urlinfo variable.

Next week we will go over more PHP tools and functions that are useful in a network environment. 

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

chat