Web Hosting Talk







View Full Version : Tutorial: PHP Includes


Dan L
10-16-2005, 02:56 PM
PHP includes are a great way to make editing sites easier. By creating a template and replacing the content with this PHP script, it will allow the page to get separate content files, with only the content in them. This is helpful as only one file needs to be changed when the template is edited.

PHP is generally better than SSI (server-side includes) since it allows for much more to happen. The below script has error-checking, default pages, and other features which SSI is not as well suited for.

The first thing to understand is how we get the content. The three main functions I like to use are include, require, and file_get_contents. There are other ways, but these three are the most common and appropriate for what we are doing.

include
The include function is used to take the exact code from a file. The code is parsed (which means any PHP code in the file will be run), and then placed exactly where the include is (in PHP's memory, this will not change your file.)

require
The require function is identical to include. The only difference is that it stops the script's execution if the file does not exist.

file_get_contents
The file_get_contents function is most similar to an include. This function does not parse the specified file, making it ideal for scripts only including text. It is also much faster than an include.

For the following examples, I will be using file_get_contents, since it is more efficient than include, and most cases will not involve files using PHP. I would also like to note that the files may be of any type, so you can include a .dat, .php, .txt, or any file wanted.

Code so far:

<?php
file_get_contents('file.txt');
?>


Next, we will check if the file being included exists. This eliminates the need to use require, and allows the specification of a default page. The function used is file_exists.

Code so far:

<?php
$file = 'file.txt';
$default = 'default.txt';
if(file_exists($file))
{
file_get_contents($file);
}
elseif(file_exists($default))
{
file_get_contents($default);
}
else
{
echo 'Could not find any files!';
}
?>


With the above code, you will notice two file_exists. These check to make sure both the requested and default file exist, and allow for an error message if neither is found.

Most instances for using this code will require a file to be included based on a variable. We will assume that variable is stored in $_GET['page']. (The URL would look like: index.php?page=info)

The problem with the above method, is that someone could specify the path to a file containing your passwords, and effectively gain access to your system. To prevent this, I append the file type to the $_GET variable.

Final Code:

<?php
$ext = '.txt';
$file = $_GET['page'].$ext;
$default = 'default'.$ext;
if(file_exists($file))
{
file_get_contents($file);
}
elseif(file_exists($default))
{
file_get_contents($default);
}
else
{
echo 'Could not find any files!';
}
?>


Believe it or not, that is all there is to it. This code can safely and efficiently include any file, and allows for a default file if none other if found.

CaseyG
10-22-2005, 01:26 AM
Very nice and detailed! Will surely help someone out.

ArcticPro43
10-24-2005, 06:14 PM
Thanks, just what I needed Dan!

Zubair1
10-27-2005, 10:03 PM
cool thanks

Korvan
11-23-2005, 06:13 PM
It is important to note that it is sometimes better to use include_once() or require_once() instead of include() and require(). Use include_once() on files that will throw an error if exicuted twice. (For instance files with PHP classes and CONSTANTS)

Also there is a security hole in the above code. The script there will allow a user to open text files not in the webhosting directory
for example
index.php?page=../../../WINDOWS/system32/eula
on a host using windows

<?php
$ext = '.txt';
$file = '../../../WINDOWS/system32/eula'.$ext;
$default = 'default'.$ext;
if(file_exists($file))
{
file_get_contents($file);
}
elseif(file_exists($default))
{
file_get_contents($default);
}
else
{
echo 'Could not find any files!';
}
?>

would give them access to the eula.txt in the windows/system32 assuming that the web host's user has acceptable read permission level (and if the hosting directory is 3 folders from the root otherwise more or less "../" could be added). If you didnt restrict the ext at all they could gain access to a servers configuration files.

dotcomguy01
11-23-2005, 08:52 PM
great work danx and korvan! keep it up!

Dan L
12-02-2005, 03:28 PM
Thanks for the tip Korvan, so here's a fix:
Replace:$file = $_GET['page'].$ext;
With:$file = ereg_replace('../','',$_GET['page']).$ext;
That will strip out all '../' instances.

mycroftx
12-03-2005, 09:06 PM
If it wasn't copied then it's a nice tutorial. If someone is interested in learning then i know a good place where to start. http://www.w3schools.com/php/default.asp.

Dan L
12-05-2005, 10:56 PM
I wrote it myself.

w3schools is okay if you want to dabble in it, but you basically just have to read from a lot of different sources and experiment. php.net's function reference is by far the best resource.

Korvan
12-06-2005, 02:36 PM
Use str_replace when just replacing strings instead of expressions. str_replace is 5x faster than ereg_replace and 12x faster than preg_replace. Not that a few microseconds will matter in most cases. This is only true on small strings, preg_replace becomes faster on much larger strings, but ereg_replace is always slower.

Aran11
08-03-2010, 04:14 PM
Would also recommend using:

<?php
include_once("inc/sql.php");
?>


This precents the same file being included more than once which becomes a simple mistake to make as your scripts grow.

rallport
12-18-2010, 09:25 AM
Thanks for the tip Korvan, so here's a fix:
Replace:$file = $_GET['page'].$ext;
With:$file = ereg_replace('../','',$_GET['page']).$ext;
That will strip out all '../' instances.

It's considored bad practice to include files based on user input. At least have an array of allowed files before you do the actual include.

mahesh2010
02-24-2011, 03:19 AM
Hi,
I have never seen such a detailed info on tutorials
thanks for sharing Nice post keep it up

KnownHost-Sven
02-24-2011, 04:49 AM
A better way is to use a switch statement and have all the pages in there:

switch($_GET['page'])
{
case 'about':
include("about.php");
break;
case 'contact':
include("contact.php");
break;
case 'home':
default:
include("home.php");
break;
}


This way it's not possible to include other files.