The manual Page
Version française
   
index | glossary | news | downloads | links ]
  PHP home page
pages
guest book
news
print button
 
news
glossary
links
downloads
 
credits
contact
 
 
search
 
last update
19/02/2003
Valid HTML 4.0!
Valid CSS!
Hit-Parade
Mesurez votre audience


  The "printable format" button

Goal of the script

The goal of this PHP script is to provide a fast way of displaying web pages of this site without frames and tables, so that they can be printed without any troubles. Indeed, pages with fixed-width tables cannot be easily printed.

On a programming point of view, there are 2 main constraints we want to avoid: not to write pages twice (one version with frames and tables and another version without) and to be able to (statically) include a footer at the bottom of all pages (different from the one used on real pages). The called script must be able to transform each page so that it would comply with these constraints.

There are at least two methods to realize this script. One of them uses an environment variable that Apache provides to PHP: $HTTP_REFERER, and the other method uses the environment variable $PHP_SELF. This site uses the second method. We will see later why. Both methods only differ from the way to calculate the path to the file to be printed out.

With $HTTP_REFERER

Principle

It is very simple: actually, some web servers provide environment variables to (CGI) scripts, and one of those variables contains the URL of the page that has called the current page. This variable is called $HTTP_REFERER.

If you click on the printer icon at the bottom of this page, you Internet browser and then the web server will send to the print.php3 script a variable $HTTP_REFERER whose value would be /www2.themanualpage.org/php/sources/print.php3. We are going to use this to open the calling file in read mode, parse it and keep only what is valuable.

This variable is really useful, but unfortunately, there are 2 problems with it. First of all, the browser agent sets it when it queries the web server to retrieve the web page, but unfortunately, many browsers do not set this variable. The second problems is that this variable is provided by Apache Web servers, but there is no guarantee that other Web servers do it as well. Consequently, a lot of visitors will never be able to use correctly the "printable format" button, because of the Web agent or the Web server. This is why this web site implements the second solution that does presents these drawbacks.

Implementing the script

There are 2 things to do: write the script print.php3, but also find a way for pages to call this script correctly. This latter operation can be simply performed by inserting a simple and direct HTML link to the script:

<A href="/utils/print.php3">printable format</A>

This piece of code should be inserted in every page we want to be printable.

For the script, the very first thing to do is to check the content of $HTTP_REFERER. We first check if it is empty or not (this can happen) and if the PHP script has been called by a page from this web site:

if (($HTTP_REFERER == "") || (! eregi("themanualpage.org",
                                      $HTTP_REFERER))) {
	echo "Oups ! Impossible d'ouvrir le fichier !";
	echo "Sorry! I cannot open this page.";
}

If everything is all right, we parse this variable to get all relevant data (in particular the name of the source page) with the function parse_url:

$url = parse_url($HTTP_REFERER);

$url is then an associative table that contains in particular a field called path. This field will be used to determine the file to open. This field may not contain any valid name (file with a .php3 extension). This happens when the script has been called from a index.php3 page; we must then add this name:

if (! eregi("\.php3", $url["path"])) {
	$nom = $url["path"]."index.php3";
} else {
	$nom = $url["path"];
}

With $PHP_SELF

Principle

It is basicly the same: we are going to use another environment variable ($PHP_SELF) to calculate the path to the file to be printed out, but this variable corresponds to the name of the script that is being executed. This means that this variable has only the proper value inside the page we want to print. Therefore, we will have to pass this variable to print.php3 as an argument with thanks to the HTTP GET method (the link to print.php3 will have a special format).

The variable $PHP_SELF is very interesting because it always exists and is correctly set, because it is set by the PHP interpreter.

Implementing the script

It is possible to pass variables to any script through URLs (GET method). For instance instance, script.php3?foo=bar will transmit the variable foo set to "foo" to script.php3. The following piece of code should be added at the bottom of every page we want to print:

<A href="/utils/print.php3?page=<? echo ereg_replace("\/www\.themanualpage\.org", "", $PHP_SELF); ?>" target="_blank"> printable format</A>

print.php3 will get a variable $page that will contain the absolute URL to the page we want to print. For example: /php/sources/print.php3.

To write print.php3, we first check that is variable is correctly set:

if ($page == "") {
	echo "Oups ! Impossible d'ouvrir le fichier !";
	echo "Sorry! I cannot open this page.";
}

Like the version with $HTTP_REFERER, it is possible no .php3 file is specified. In this case, we must correct this by adding index.php3:

if (! eregi("\.php3", $page)) {
	$nom = $page."index.php3";
} else {
	$nom = $page;
}

From now on, and in these conditions, $nom is equivalent to $nom we got from the previous version of the script. What we still have to do is exactely the same.

End of the script

From $nom, it is easy to deduce the absolute local path to the document we want to print:

$fichier = fopen($REDIRECT_HOMEDIR.$nom, "r");

Now, we just have to parse the file and locate lines where we perform an "include" (those lines should be removed). One must take care of images, since we need to transform relative pathes into absolute pathes:

while (! feof($fichier)) {
	$ligne = fgets($fichier, 4096);
// On traite le cas particulier des liens relatifs dans les
// images : il faut en faire des liens absolus
//
// Particular case: relative pathes of images must be changed
// into absolute pathes
	if (eregi("<img ", $ligne)) {
		if (! eregi(" src=\"/", $ligne) &&
		    ! eregi("src=\"http://", $ligne)) {
			$ligne = eregi_replace(" src=\"(.*)\"",
			         " src=\"".dirname($nom)."/\\1\"",
			         $ligne);
		}
	}
	if (! eregi("<\? include\(.*\)\; \?", $ligne)) {
		echo $ligne;
		if (eregi("</HEAD>", $ligne)) {
			echo "<BODY bgcolor=\"#ffffff\">\n";
			echo "<H1>".$metatags["title"]."</H1>\n";
		}
	}
}

At the end of the script, we add a common footer. As this site is both in French and English, the footer must be changed according to the language. To do so, we simply check the name of the treated file to find a "uk_" in:

if (ereg("uk_", $HTTP_REFERER)) {
	message in English
} else {
	message in French
}

Useful functions

name description
$HTTP_REFERER URL of the calling page
$PHP_SELF absolute URL to the currently running script
parse_url returns a table with the different parts of an URL (server, resource...)
fopen open a file (absolute path on the local hard drive)
feof tells if we have reached the end of the file
fgets reads a given amount of characters in a file
fclose close a file open with fopen
dirname complete directory path to the specified file
ereg and eregi function used to guess if a string contains another string (the second function is the case-insensitive version)

Download the code with $HTTP_REFERER

Download the code with $PHP_SELF

printable format printable format



Copyright © 2000-2002 themanualpage.org - This site is submissive to the terms of the GNU GPL and FDL licences.