@ jimmy dot axenhus at gmail dot com
Your example
<?php
if(include './foo.php' && $bar = "bar") {
echo "FooBar";
}
?>
evaluates as
<?php
if(include ('./foo.php' && $bar = "bar")) {
echo "FooBar";
}
?>
Therefore you have to use
<?php
if((include './foo.php') && $bar = "bar") {
echo "FooBar";
}
?>
(See Example #4 of the documentation)
include()
La fonction include() inclut et exécute le fichier spécifié en argument.
Cette documentation s'applique aussi à la fonction require(). Les deux structures de langage sont identiques, hormis dans leur gestion des erreurs. Ils produisent tous les deux un Alerte mais require() génère une erreur fatale. En d'autres termes, n'hésitez pas à utiliser require() si vous voulez qu'un fichier d'inclusion manquant interrompe votre script. include() ne se comporte pas de cette façon, et le script continuera son exécution. Assurez-vous d'avoir bien configuré le include_path aussi. Soyez prévenus qu'une erreur d'analyse dans un fichier inclut ne cause pas l'arrêt du script en PHP dans les versions antérieures à 4.3.5. Depuis ces versions, il le peut.
Les fichiers à inclure sont d'abord recherchés dans chaque dossier de include_path, relativement au dossier courant, puis dans le dossier de travail du script. Par exemple, si include_path est ., que le dossier de travail est /www/, et que vous incluez le fichier include/a.php et qu'il y a une instruction include "b.php" dans ce fichier, alors b.php est d'abord recherché dans /www/libraries/, puis dans /www/include/. Si le nom du fichier commence par ./ ou ../, il est cherché uniquement dans le dossier courant d'exécution.
Lorsqu'un fichier est inclus, le code le composant hérite de la portée des variables de la ligne où l'inclusion apparaît. Toutes les variables disponibles à cette ligne dans le fichier appelant seront disponibles dans le fichier appelé, à partir de ce point. Cependant, toutes les fonctions et classes définies dans le fichier inclus ont une portée globale.
Exemple #1 Exemple avec include()
vars.php
<?php
$couleur = 'verte';
$fruit = 'pomme';
?>
test.php
<?php
echo "Une $couleur $fruit"; // Une
include 'vars.php';
echo "Une $couleur $fruit"; // Une verte pomme
?>
Si l'inclusion intervient à l'intérieure d'une fonction, le code inclus sera alors considéré comme faisant partie de la fonction. Cela modifie donc le contexte de variables accessibles. Une exception à cette règle : les constantes magiques sont analysées par l'analyseur avant que l'inclusion n'intervienne.
Exemple #2 Inclusion de fichiers dans une fonction
<?php
function foo() {
global $couleur;
include 'vars.php';
echo "Une $couleur $fruit";
}
/* vars.php est dans le contexte de foo() *
* donc $fruit n'est pas disponibles hors de *
* cette fonction. $couleur l'est, car c'est *
* une variable globale */
foo(); // Une verte pomme
echo "Une $couleur $fruit"; // Une verte
?>
Il est important de noter que lorsqu'un fichier est include() ou require(), les erreurs d'analyse apparaîtront en HTML tout au début du fichier, et l'analyse du fichier parent ne sera pas interrompue. Pour cette raison, le code qui est dans le fichier doit être placé entre les balises habituelles de PHP.
Si les Gestionnaires d'URL sont activés dans PHP (ce qui est le cas par défaut), vous pouvez localiser le fichier avec une URL (via HTTP ou bien avec un gestionnaire adapté : voir Liste des protocoles supportés pour une liste des protocoles), au lieu d'un simple chemin local. Si le serveur distant interprète le fichier comme du code PHP, des variables peuvent être transmises au serveur distant via l'URL et la méthode GET. Ce n'est pas, à strictement parler, la même chose que d'hériter du contexte de variable. Le fichier inclus est en fait un script exécuté à distance, et son résultat est inclus dans le code courant.
Les versions Windows de PHP antérieures à la version 4.3.0 ne supportent pas l'accès aux fichiers distants avec cette fonction, même si allow_url_fopen est activé.
Exemple #3 Utiliser include() via HTTP
<?php
/* Cet exemple suppose que www.example.com est configuré pour traiter
* les fichiers .php et non pas les fichiers .txt. De plus,
* 'Work' signifie ici que les variables
* $foo et $bar sont disponibles dans le fichier inclus
*/
// Ne fonctionne pas : file.txt n'a pas été traité par www.example.com comme du PHP
include 'http://www.example.com/file.txt?foo=1&bar=2';
// Ne fonctionne pas : le script cherche un fichier nommé
// 'file.php?foo=1&bar=2' sur le système local
include 'file.php?foo=1&bar=2';
// Réussi
include 'http://www.example.com/file.php?foo=1&bar=2';
$foo = 1;
$bar = 2;
include 'file.txt'; // OK.
include 'file.php'; // OK.
?>
Alerte de sécurité
Un fichier distant peut être traité sur le serveur distant (dépendemment de l'extension du fichier et si le serveur distant exécute PHP ou non) mais il doit toujours produire un script PHP valide parce qu'il sera traité sur le serveur local. Si le fichier du serveur distant doit être traité sur place et affiché seulement, readfile() est une fonction beaucoup plus appropriée. Autrement, vous devriez bien faire attention à sécuriser le script distant afin qu'il produise un code valide et désiré.
Voir aussi travailler avec les fichiers distants, fopen() et file() pour des informations reliées.
Gestion du retour : il est possible d'exécuter une commande return() dans un fichier inclus pour en terminer le traitement et retourner au fichier appelant. De plus, il est possible de retourner des valeurs des fichiers inclus. Vous pouvez prendre et traiter la valeur retournée par la fonction, comme toute autre fonction. Ce n'est cependant pas possible lors de l'inclusion de fichier distant à moins que le fichier distant a des balises valides de début et de fin de script PHP (comme avec les fichiers locaux). Vous pouvez déclarer les variables nécessaire dans ces tags et elles seront introduites à l'endroit où le fichier a été inclus.
Comme include() est une structure de langage particulière, les parenthèses ne sont pas nécessaires autour de l'argument. Faites attention lorsque vous comparez la valeur retournée.
Exemple #4 Comparaison de la valeur de retour d'un include
<?php
// ne fonctionne pas, évaluer comme include(('vars.php') == 'OK'), i.e. include('')
if (include('vars.php') == 'OK') {
echo 'OK';
}
// fonctionne
if ((include 'vars.php') == 'OK') {
echo 'OK';
}
?>
Exemple #5 include() et return()
return.php
<?php
$var = 'PHP';
return $var;
?>
noreturn.php
<?php
$var = 'PHP';
?>
testreturns.php
<?php
$foo = include 'return.php';
echo $foo; // affiche 'PHP'
$bar = include 'noreturn.php';
echo $bar; // affiche 1
?>
$bar a la valeur de 1 car l'inclusion était réussie. Notez la différence entre les deux exemples ci-dessus. Le premier utilise la commande return() dans le fichier inclus, alors que le second ne le fait pas. Si le fichier ne peut être inclus, FALSE est retourné et une erreur de niveau E_WARNING est envoyée.
S'il y a des fonctions de définies dans le fichier inclus, elles peuvent être utilisées dans le fichier principal si elles sont avant le return() ou après. Si le fichier est inclus deux fois, PHP 5 enverra une erreur fatale car les fonctions seront déjà déclarées, tandis que PHP 4 ne se plaindra pas des fonctions définies après return(). Il est recommandé d'utiliser include_once() au lieu de vérifier si le fichier a déjà été inclus et donc de retourner conditonnellement l'inclusion du fichier.
Une autre façon d'inclure un fichier PHP dans une variable est de capturer la sortie en utilisant les fonctions de contrôle de sortie avec include(). Par exemple :
Exemple #6 Utilisation de la sortie du buffer pour inclure un fichier PHP dans une chaîne
<?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;
}
?>
Pour automatiquement inclure des fichiers dans vos scripts, voyez également les options de configuration auto_prepend_file et auto_append_file du php.ini.
Note: Comme ceci est une structure du langage, et non pas une fonction, il n'est pas possible de l'appeler avec les variables fonctions.
Voir aussi require(), require_once(), include_once(), get_included_files(), readfile(), virtual() et include_path.
include
15-Nov-2008 07:53
06-Nov-2008 07: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 05: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 07: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 06: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 08: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-Sep-2008 05:17
Never use include in an if statement.
<?php
if(include('./foo.php') && $bar = "bar") {
echo "FooBar";
}
?>
This will not include the file foo.php, instad it will for some reason onclude the file "1" and print:
Warning: include(1) [function.include]: failed to open stream: No such file or directory in (file) on line (line)
Warning: include() [function.include]: Failed opening '1' for inclusion (include_path='.;C:\php5\pear') in (file) on line (line)
This will also fail if you write:
<?php
if(include './foo.php' && $bar = "bar") {
echo "FooBar";
}
?>
This will not, however, fail if you write:
<?php
if(include('./foo.php')) {
echo "FooBar";
}
?>
PHP version: 5.2.5
05-Sep-2008 11:59
I have another function implementation of the include_text, that works better but makes use of the filesystem... Here it is :
<?php
function include_text($__text,$__exported){
foreach($__exported as $__name => $__value) {
$$__name = $__value;
}
$__filename = tempnam('/tmp/','Form');
file_put_contents($__filename,$__text);
ob_start();
include $__filename;
$__contents = ob_get_contents();
ob_end_clean();
unlink($__filename);
return $__contents;
}
?>
Usage example (the code speaks for itself) :
<?php
// ....
$exportedVars['Names'] = $Names;
$exportedVars['Data'] = $Data;
$includedResult = include_text($importedText,$exportedVars);
echo $includedResult; // Or make anything you want with it
// ....
?>
Note : it works nicely but doesn't return the exported vars if they are changed. I didn't neede that, so figure it out yourself if you need it (and share it !)
03-Aug-2008 06:08
in response to pepesantillan at gmail dot com
here is a much simpler way of accessing the entire global scope from within a function, reguardless of variable types.
test.php
<?php
function my_include($file) {
//get access to all globals
foreach ($GLOBALS as $key => $val) { eval("global \$$key;"); }
//include our file
include($file);
}
$example = 1;
my_include('example.php');
echo $example;
?>
example.php
<?php
$example = 2;
?>
display:
2
17-Jul-2008 10: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 08:29
Here's how to send headers with a URL include, if you'd like:
http://www.mooreds.com/wordpress/archives/000477
25-Jun-2008 07: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 03:52
Don't forget about the DIRECTORY_SEPARATOR constant.
No tricks needed to identify the OS;
just use it:
include($folder.DIRECTORY_SEPARATOR.$file;)
*hint make a function
18-Jun-2008 02:13
The code in EXAMPLE #5 above does NOT work if you attempt to include by URL. I have been unable to discover any scheme at all that will pass a variable in this manner.
16-Jun-2008 03:46
Thanks to alex carstea and tim furry for absolute path function. Here is (just) a bit faster version :
<?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.
function getFilePath($relative_path) {
// $abs_path is the current absolute path (replace "\\" to "/" for windows platforms)
$abs_path=str_replace("\\", "/", dirname($_SERVER['SCRIPT_FILENAME']));
$relative_array=explode("/",$relative_path);
$abs_array=explode("/",$abs_path);
// for each "../" at the beginning of $relative_path
// removes this 1st item from $relative_path and the last item from $abs_path
while ($relative_array and ($relative_array[0]=="..")) {
array_shift($relative_array);
array_pop($abs_array);
}
// and implodes both arrays
return implode("/", $abs_array) . "/" . implode("/", $relative_array);
}
?>
14-May-2008 08: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));
}
}
?>
14-May-2008 01:01
A note about the "return - thing":
test2.php
<?php
$r = true;
return $r;
?>
test1.php: (Does NOT work)
<?php
function functionA(){
return functionB();
}
function functionB(){
require_once 'test2.php';
}
var_dump(functionA());
?>
When you call test1.php, result will be NULL.
You have to "return" the include like this:
test1.php CORRECT:
<?php
function functionA(){
return functionB();
}
function functionB(){
return require_once 'test2.php';
}
var_dump(functionA());
?>
12-May-2008 07: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 06: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.
01-May-2008 01:18
It aggravated me trying to get an absolute URL include from another one of my sites; then it occurred to me to check the phpinfo().
Under the "PHP Core" section; look for these values:
allow_url_fopen
allow_url_include
Turns out, both of mine are turned off. If you are stuck, try this snippet that {oasis1 (at) geocities (d@t) com} wrote earlier:
<?php
$times = substr_count($_SERVER['PHP_SELF'],"/");
$rootaccess = "";
$i = 1;
while ($i < $times) {
$rootaccess .= "../";
$i++;
}
include ($rootaccess."path_to_script");
?>
Thanks a ton Oasis!
10-Mar-2008 05:09
include() statement generates a compilation-time error when used inside a class declaration (but not within a function). For example:
<?php
class MyClass
{
include "file1.php";
include "file2.php";
function func1()
{
.......
}
?>
25-Feb-2008 02: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-Dec-2007 10:13
In response to the last post...
instead of using your function to include a file, you can directly include files. But I guess my_include does something else besides including files and thats why you use it.
Im learning php (just got to this part of the manual, that much of a begginer I am) but a solution I can think of (and I am posting it because your post is from about a day ago) is using an array as a parameter in the function my_include. That array would contain all your local (global) variables and would pass them to your function and made them local for that function... Heres and example (hoping its not so hard to understant)
<?php
//sample function, note the referencing of the array using &
function my_include($file_to_include,&$my_array_of_globals) {
//you can find explanation on the function extract
//from the function list on this page, always check
//that list, is really usefull!. Extract would go at the very
//beggining of the function my_include.
extract($my_array_of_globals);
//now you have a kind of simulation of using global with
//any single variable of your script
include($file_to_include);
//in this part we recreate the array containing our variables
//this would go at the very end of the function
$my_array_of_globals = compact(array_keys($my_array_of_globals));
}
//some variables
$var1 = 1;
$var2 = 3;
echo "First print before calling the function:<BR>\$var1 is $var1, \$var2 is $var2<BR>";
//in this part we create an array containing our variables
//this is the array we will pass to the function
foreach ($GLOBALS as $key => $value){
if (!is_array($value)) {
//is not array? what?... yup, just to avoid post, get, cookie, etc...
//and what if I have a variable that its an array?
//as sad as it is for me, my method wont allow you
//to get arrays back from the function
$some_globals["$key"] = $value;
}
}
//and we call our function using this array
$include_string = $_SERVER["DOCUMENT_ROOT"]."/include_me.php";
//I like using include without the help of php.ini include_path
my_include($include_string,$some_globals);
//after that we extract our variables from $some_globals
extract($some_globals);
echo "Second print, after calling the function:<BR>\$var1 is $var1, \$var2 is $var2<BR>";
?>
This is include_me.php
<?php
// sample included file, it could try to access some variables
//from the file including him and even try to change them
$var1++; //from var1 = 1 to var1 = 2
$var2 *= 2; //from var2 = 3 to var2 =6
?>
and the output:
First print before calling the function:
$var1 is 1, $var2 is 3
Second print, after calling the function:
$var1 is 2, $var2 is 6
It is not an elegant nor efficient solution, but I wanna try to help you with the little knowledge I have. Hope it is of any help! Hope someone else posts a solution!
Merry Christmass to everyone
24-Oct-2007 08: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 11: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.
02-Sep-2007 12:29
Reponse to rayro at gmx dot de (21-Aug-2007 11:48 )
Hi rayro,
your code :
<?php
include(realpath('../../../test.php'));
?>
..Don't works when a function is called by another remote function (with a another remote include) -> realpath don't use __FILE__ reference :(
This works always and everywhere ( thanks to Jonny Rylands http://fr2.php.net/manual/fr/function.realpath.php#56773 ) :
<?
include (realpath(dirname(__FILE__).'/relative/path/to/include.inc.php'));
?>
friendly.
30-Aug-2007 07: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.
16-Aug-2007 06:17
In reference to the fopen() and $use_include_path workaround for checking whether a include file exists as posted by [arnold at bean-it dot nl]...
I did some benchmarks with 100 dirs (each with 1 file) in the include_path on Apache/2.0.55 (Win32) PHP/5.2.1.
Here are the results:
(note: in the success scenarios, I am include'ing the file in the LAST directory on the include stack. This is to maximize the seek time; fail scenarios simply use a non-existent file; all times are in seconds )
benchmarks --> plain vanilla INCLUDE
(success)
0.05515718460083
0.054859161376953
0.053768157958984
(fail)
0.22402501106262
0.17378783226013
0.14510798454285
benchmarks --> fopen() and $use_include_path workaround
(success)
0.060588836669922
0.069549798965454
0.056423902511597
(fail)
0.05295991897583
0.039775133132935
0.054499864578247
>>> CONCLUSION
In cases involving MANY include paths, include() is -marginally- faster than the workaround (unsurprising - we incur the extra overhead of BOTH the fopen() call AND the $use_include_path seek). I say marginal in comparison to the "fail" scenarios, detailed next..
The most surprising thing is the inefficiency of include() when you are trying for a non-existent file. As compared to the workaround, the native include() method is roughly 3 times slower.
Based on additional tests (50 paths only), I note that any decrease in seek time for either case is generally linear to the number of paths.
---
THEREFORE, depending on the amount of paths you have, you might want to resort to different methods of optimizing the includes in your scripts, especially if you need to constantly test for the existence of include'd files (our organization uses a templating engine that relies on a virtual flat directory structure using the set_include_path() function).
---
From a technical perspective, I have no idea why this is the case and I find the prospect of trawling the PHP source to be rather daunting. However, as an educated guess: I figure that the include() code assumes the file exists, and so wastes processor cycles making a system read call, which inevitably fails.
For those interested in the benchmark script, you can email me at the email address provided above. No support, of course. :P
09-Aug-2007 05:09
A small tweak to alex's getFilePath function allows it to work for Windows-based PHP as well:
<?php
$absPath = str_replace("\\", "/", dirname($_SERVER['SCRIPT_FILENAME']));
?>
Windows recognizes a forward slash as a directory separator character.
Using $_SERVER['DOCUMENT_ROOT'] and similar solutions didn't seem to work for web paths with internal symbolic links. Alex's function gets around that and works great.
26-Jul-2007 05: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 08: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 01: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
03-Jul-2007 02:22
In response to oasis1 below, I use mod_rewrite to pipe all my requests through the index.php file, so I'm able to use the below code to find the root directory:
$sRoot = $_SERVER['HTTP_HOST'] . dirname($_SERVER['SCRIPT_NAME']);
You may be able to modify it to suit yourself.
29-Jun-2007 05: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 11: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:
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.
21-May-2007 05:38
Regarding the caching of includes.
I submitted a bug for this, apparently it's not a bug it's supposed to work that way for some reason.
The bugs team declined to elaborate as to why but it would seem includes aren't meant to use dynamic code, which makes this function worthless and by extension makes php needlessly time consuming because you can't reuse files properly.
17-May-2007 04:26
I needed to use an include with an echo statement, with http authenication so I thought I'd share. It's basic but I didn't find it documented anywhere:
include 'http://treyh:pass@192.168.0.60/update2_count3.php?data=' . $row[id];
Even when you set cache control and expiry headers:
header("Expires: 0");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("cache-control: no-store, no-cache, must-revalidate");
header("Pragma: no-cache");
It doesn't seem to reparse the include on the second hit to the page without a forced refresh.
e.g. a page where you direct to a login page which changes a $_SESSION var then returns to the originating page.
The originating page doesn't execute the code so it looks like still not logged in.
01-May-2007 07:03
I wanted that included files behave like in C/C++ and this was killing me. So I created this function that really helped me (Note: You should add these lines to EVERY included file).
Code Lines:
<?
$FILE_PATH = preg_replace_callback(
'/(.*)(\\\?.*?)\s*;\1(\\\?.*?)\s*$/',
create_function(
'$matches',
'$path = str_replace("\\\", "/",(isset($matches[2])?
preg_replace(
\'/(?:^\/|^\\\\\)?[^\/\\\\\]+(?:\/|\\\\\)?/\',
"../",$matches[2]):"./").
(isset($matches[3])?$matches[3]:""));
return !empty($path)? "$path/" : "./";'
)
,realpath("./").";".dirname(__FILE__)
);
?>
Usage Example:
Files hierarchy for example
/www/file.php
/include/secondfile.php
/include/test/anotherfile
<? //file.php
//i will not include the code lines in example to avoid repetition but you have to
// --- FILE_PATH code lines here ---
// include the file relative to the caller position remember to use a relative path from each file to desired file
include ($FILE_PATH . "../../include/secondfile.php");
?>
<? //secondfile.php
// --- FILE_PATH code lines here ---
//note that path used is in reference to secondfile.php's path and not the original caller's(file.php) path
include ($FILE_PATH . "test/anotherfile"); //or include ($FILE_PATH . "./test/anotherfile");
?>
<? //anotherfile
/* --- some mixed content here --- */
?>
Now you can do recursive includes to files inside already
included files using each file's path as reference, like in
c/c++!!!
I'd tested this just in WINXP (PHP Version 4.4.1), so, I
dont know how it behaves in other OS/PHP-Versions. Any
additional suggestions or bugs, please let me know.
09-Mar-2007 04:36
In response to baofu:
The problem with calling:
set_include_path( ... )
before including any file, is that if one of the included files, in turn, does a set_include_path to include yet another bunch of files, then the following include statement in your topmost file, is done in an include path context that has changed.
Using: include dirname(__FILE__).'/../foo/bar' remains the best solution.
23-Feb-2007 08:43
This might help a bit for security (no guarantees).
Instead of
include $page;
put
include str_replace('../', '', './' . $page);
23-Feb-2007 12:47
coldflame,
<?=$foo?> equals <? print $foo ?>
If 1 is not needed at the end, just use <? include($filename) ?> without the equal sign.
13-Feb-2007 02:49
Be careful using the <?= / ?> start and end tags with include / require.
A lovely feature/bug/misunderstanding meant that the result of
<?=include(filename)?>
was to get the contents of the file, suffixed with a '1'. I can only assume that the one is the return code of the include.
hopefully my pain can help somebody else :D
cheers,
coldflame
10-Feb-2007 06: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 11: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 10: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:
<?
$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.
18-Jan-2007 05:06
In reply to the last anonymous note, this is exactly the way mediawiki code handles this problem. They have various-depth include paths.
So, for instance, inside includes/normal/UtfNormal.php (as of revision 19455) they do:
<?php
require_once dirname(__FILE__).'/UtfNormalUtil.php';
?>
...to include the file includes/normal/UtfNormal.php.
10-Jan-2007 12: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.
01-Jan-2007 03:42
I'm gonna throw my hat in the rink and also say that I've always thought that the include path being relative to the current directory is silly. PHP is the only language I can think of that does this. Almost all of my include paths have always had to be prefixed with <?php dirname(__FILE__) ?> to operate expectedly.
28-Dec-2006 08:27
I have to agree with sean dot farrell at digital-egg dot org.
If I put "../" or "./" in a call to include(), I expect it to be relative to the file I am including from, not the current working directory of the application.
This backwards mentality for relative paths really interferes with PHP's ability to build packages of files independent of an application.
29-Nov-2006 03:12
The way PHP handles the ./ and ../ is totally counter intuitive. As said if the included file is preceded by a ./ and ../ it looked up from the current working directory. And that is defined by the of the EXECUTED script. That is the script that you specified in the url.
So if your have a.php that includes include/b.php that includes ../extern/c.php, it will not do what you want. You can use extern/c.php instead if you never execute outside of the document root. For me that just will not cut it. Since I execute test suites if files are directly called, like in python.
Here is my dirty trick that works, since I only have two levels of file hierarchy:
set_include_path("../:./");
require_once("extern/c.php");
And here is an open question: Why are the included files not looked up relative from the file that includes them and then in the include path? This would be a behavior like in all other languages.
16-Nov-2006 10:03
In response to http://uk.php.net/manual/en/function.include.php#38000
Using the following at the top of your CLI scripts will make includes work similar to web PHP.
#!/usr/bin/php
<?php chdir(dirname(__FILE__)); ?>
This changes the current working directory to the one your script is running in. Its quite used for taking existing web scripts and getting them to run quickly in the command line.
16-Nov-2006 04: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:
<?
test();
include 'file2.php';
?>
file2.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 05: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
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 01: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;
}
?>
19-May-2006 11:40
at spam guard dot gmail com
to php dot net at reinsveien dot com:
if you know the domain the file should be coming from then you can parse the variable for the domain and make sure that it matches the domain you expect, example:
<?php
$path="/full/path/to/script/";
if (getdomain($path) == 'yourdomain'){
include($path.'somefile.php');
}
?>
this should prevent remote execution of any malicious script
08-May-2006 09:15
What cavarlier refers to is that on some editors, UTF-8 files are prefixed with a BOM (Byte Order Mark), an invisible marker three bytes in size, which are output by PHP if it encouters them (which is before the <?php on the first line). Notepad is particularly notorious creating these.
However, 