Here is my directory tree:
/
index.php
include/
functions.php
head.php
connect.php
sub/
index.php
In my head.php and connect.php both have:
include_once 'include/functions.php';
My index.php in the root folder includes these two: head.php and connect.php like this:
include_once 'include/connect.php';
include_once 'include/head.php;'
However, when my index.php in sub/ includes functions.php and head.php, they would fail to also include functions.php.
Here's how I included in the sub/index.php:
include_once '../include/connect.php';
include_once '../include/head.php';
If I change in the head.php and connect.php to: include_once '../include/functions.php';
The sub/index.php would include everything normally but the index.php in the root would fail to load the functions.php.
How can I fix this?
PHP version: 5.2.*
Use the constant __DIR__ in your include statements and then move relative to that. So in sub/index.php you would do include_once __DIR__ . '../include/connect.php'
The __DIR__ is a constant that is the directory of the file that you are in.
http://php.net/manual/en/language.constants.predefined.php
If you are using php < v5.3, you can use dirname(__FILE__) to get the same thing.
The Error
Include statement error in head.php and connect.php
include_once 'include/functions.php';
The Fix
include_once 'functions.php';
OR
include_once __DIR__ . 'functions.php'; //PHP 5.3 or higher
OR
include_once dirname(__FILE__) . 'functions.php'; //PHP 5.2 or lower
The Reason
head.php and connect.php are located in the same folder as functions.php
As suggested by #Schleis, using __DIR__ (PHP 5.3+) or dirname(__FILE__); (PHP 5.2-) will allow for relative file includes.
I would suggest to set your web project root directory in every file using chdir() function, so you don't need to think about it where are you currently located and how many back-dirs ../ you need.
Use example:
chdir($_SERVER['DOCUMENT_ROOT']);
You could define constant for include path in root file and then use that constant in all other files:
define( "INCLUDE_PATH", dirname(__FILE__) . '/include/' );
// some other file
include_once INCLUDE_PATH . 'functions.php';
It is good practice to have one file like config.php in the root folder where are defined global settings like include paths etc. That way you do not have to care about relative paths anymore, and if in the future you decide to change the folder structure, instead of changing the paths in all files just change the include constant.
Related
New to PHP so trying to work out how relative and absolute paths work with require.
My structure looks like:
/index.php
/inc/db_functions.php
/inc/config.php
/login/login.php
db_functions.php includes config.php using
require_once 'inc/config.php';
index.php includes db_functions.php using require_once 'inc/db_functions.php';
If the user is not logged in then the browser redirects to login.php.
Originally login.php was in the root folder and used the same require once as index.php. It worked perfectly.
Now it is in its own subfolder.
I changed the require_once to use
require_once('../inc/db_connect.php');
The code worked until it got to the require_once line in db_connect.php and then failed.
I changed the require once in login.php to be:
require_once(__DIR__.'/../inc/db_connect.php');
Again it failed when it got to the require_once in db_connect.php
I changed the require_once in db_connect to be an absolute path. Again it failed.
Is there any way to deal with this as it seems that the include paths for an included file are changed by the location of the calling file ( which I guess makes sense) but how to make it more robust.
db_functions.php must include config.php using
require_once 'config.php'; because they are in same folder.
In general, best would be to use full paths.
I have website running perfectly on production server. I have moved it to another web server. (VPS).
Let me explain you with example:
The directory structure:
includes/
header.php
business/
index.php
some other files...
index2.php
In my previous version, I used
include_once(includes/header.php)
in index.php and index2.php. It runs fine. but in my new server setup it's giving me error regarding path (obvious).
ERROR:
include_once(includes/header.php): failed to open stream: No such file or directory
And because of that:
Fatal error: Class 'EncryptionClass' not found
I think there are some server configurations which I need to do. But, I don't know how?
Please guide me. Let me know if you want more information.
if using PHP 5.3+ Try using:
include_once(__DIR__.'/includes/header.php');
DIR is a magic constant that will return the full directory that the file is in.
You could supply an absolute file system path to the include:
include_once($_SERVER['DOCUMENT_ROOT'] . "/includes/header.php");
I would simply add your includes directory to the include_path. For example, in index2.php
set_include_path(implode(PATH_SEPARATOR, [
__DIR__ . '/includes', // relative to this file, index2.php
get_include_path()
]));
include_once 'header.php';
and similarly in business/index.php...
set_include_path(implode(PATH_SEPARATOR, [
__DIR__ . '/../includes', // relative to this file, business/index.php
get_include_path()
]));
include_once 'header.php';
Personally, I would use PSR-0 file-to-class name mappings and configure an autoloader, eg
includes/EncryptionClass.php
class EncryptionClass { ... }
index2.php
spl_autoload_register(function($class) {
require_once __DIR__ . '/includes/' . $class . '.php';
});
$encryptionClass = new EncryptionClass();
I have the following dir structure:
/app
/controlers
/models
/views
init.php
config.php
/www
index.php
/www/index.php code to call the init file:
include_once '../app/init.php';
Then in /app/init.php I have:
require_once 'config.php';
require_once 'routes.php';
For some reason the config.php file is not loading. If I rename it to config2.php and change the include, it is all good. When I switch back to the original name though, it's ignored again. Is there any chance the file name is reserved somehow?
I'm using Apache coming with XAMPP.
When you want to include a file from the same directory use
require_once './config.php';
require_once './routes.php';
or
require_once __DIR__.'/config.php';
require_once __DIR__./'routes.php';
otherwise a file with same name from your include_path may get included instead...
I tried to use the absolute path to include my files :
I have 4 files (I have other file on my localhost but oddly the inclusion works well) :
header.php (C:\wamp\www\MySite\layout\header.php)
<?php session_start ();
require_once '/pdo.php';
....
pdo.php (C:\wamp\www\MySite\pdo.php)
<?php
require_once '/class/User.php';
require_once '/class/Order.php';
....
forms/login.php (C:\wamp\www\MySite\forms\login.php)
<?php
session_start ();
include '/pdo.php';
....
login.php (C:\wamp\www\MySite\login.php)
<?php
$title = 'Connexion';
include ("/layout/header.php");
...
So it's look like :
Root
- forms
- login.php
-layout
- header.php
- pdo.php
- login.php
And I have this errors :
( ! ) Warning: include(/pdo.php): failed to open stream: No such file or directory in C:\wamp\www\MySite\forms\login.php on line 3
Call Stack
( ! ) Warning: include(): Failed opening '/pdo.php' for inclusion (include_path='.;C:\php\pear') in C:\wamp\www\MySite\forms\login.php on line 3
( ! ) Fatal error: Class 'User' not found in C:\wamp\www\MySite\forms\login.php on line 12
But I have this problem on a lot of files since I wanted to change the arboresence (tree) of files and folder ..
How I can solve this problem ? and how I can do to avoid this problem in the future ?
Thank you
I tried to use the absolute path to include my files :
header.php (C:\wamp\www\MySite\layout\header.php)
<?php session_start ();
require_once '/pdo.php';
The PHP code is executed on the server. An absolute path in this context means a file-system absolute path, not a web host path. Since you are on Windows, /pdo.php in fact means C:/pdo.php and not C:\wamp\www\MySite\pdo.php as it seems you think.
The best way to work with paths in PHP, regarding include and require is to use the __FILE__ and __DIR__ magic constants and the dirname() PHP function to build the (file-system) absolute paths of files starting from their relative locations.
Your code becomes:
header.php (C:\wamp\www\MySite\layout\header.php):
<?php
session_start ();
// 'pdo.php' is one level up
require_once dirname(__DIR__).'/pdo.php';
....
pdo.php (C:\wamp\www\MySite\pdo.php)
<?php
// User.php is inside the 'class' subdirectory
require_once __DIR__.'/class/User.php';
require_once __DIR__.'/class/Order.php';
....
dir1/dir2/dir3/file.php (C:\wamp\www\MySite\dir1\dir2\dir3\file.php)
<?php
// 'header.php' is in the 'layout' subdirectory of the grand-grand parent directory
include dirname(dirname(dirname(__DIR__))).'/layout/header.php';
Remark
The solution presented here makes the code independent of its actual location in the file system. You can move the entire project (everything in C:\wamp\www\MySite) in a different directory or on a different computer and it will work without changes. Even more, if you use forward slashes (/) as directory names separators it works on Windows, macOS or any Linux flavor.
One convention is to include a configuration file in every php script. This configuration file would set the include path, allowing you to include other files, classes, etc and would continue to work regardless of whether your current working directory had changed - it will allow you to better organise your classes and functions into meaningful directories and include them without worrying about the full path:
An example below:
Create file at C:\wamp\www\MySite\config.php
<?php
set_include_path(get_include_path() . PATH_SEPARATOR . 'C:\wamp\www\MySite\class' . PATH_SEPARATOR . 'C:\wamp\www\MySite\conf');
?>
Then in
header.php (C:\wamp\www\MySite\layout\header.php)
<?php
require_once('C:\wamp\www\MySite\config.php');
session_start ();
require_once '/pdo.php'; // put pdo.php in C:\wamp\www\MySite\conf\ directory and it will be included
....
In pdo.php (C:\wamp\www\MySite\pdo.php):
<?php
require_once 'User.php';
require_once 'Order.php';
....
My directory structure looks like this:
blog -> admin -> index.php
blog.php
db.php
functions.php
I have been trying to include (require, really) blog.php in the admin/index.php, but facing lots of errors. I'm following a PHP course, and the instructor does the same thing successfully.
admin/index.php:
require "../blog.php";
which, in turn, requires two more files in its directory.
require "db.php";
require "functions.php";
If you find that relative include paths aren't working as expected, a quick fix is to prepend __DIR__ to the front of the path you're trying to include.
require __DIR__ . "/../blog.php";
It's reasonably clean, and you don't need to modify the include path or working directory.
You need to set the include_path in your php.ini.
If you want to set it at run-time, use set_include_path().
If you are including this files db.php and functions.php in index.php then you have to write this code
require "../db.php";
require "../functions.php";
OR if you are including this files in blog.php then write this code
require "db.php";
require "functions.php";
I like to start my files with chdir($_SERVER['DOCUMENT_ROOT']). This allows me to get a nice and logical base path for all my includes.