I am trying to use absolute paths to get a definitive reference to a config file.
For this, I am currently doing this:
require_once '../config.php'; //Works fine
But when I try this:
require_once '/config.php'; //Throws error, see below
The error I get is:
require_once(): Failed opening required '/config.php' (include_path='.;C:\php\pear')
Is this a thing in PHP 5.6.0 or am I missing something?
Breaking down ../config.php:
../ goes one directory above the working directory
config.php finds the file config.php in that directory
Breaking down /config.php:
/ goes to the server root
config.php finds the file config.php in that directory
If the first one works but not the second, it means that the file config.php is not in the root folder, but is in the parent directory of the working file.
If you explicitly set the includes path in your script to the actual location it should be quite simple to include the files you need such as:
set_include_path( $_SERVER['DOCUMENT_ROOT'] . DIRECTORY_SEPARATOR );
require_once( 'config.php' );
Related
I have file /root/update/test.php. There's also a file, /root/connect.php; This file has a line
include "../config.php";
In /root/update/test.php. There's the code
set_include_path(".:/root");
include "connect.php";
When I run /root/update/test.php, it finds connect.php, but fails to find config.php, giving me
PHP Warning: include(../config.php): failed to open stream: No such file or directory in /root/connect.php on line 2
PHP Warning: include(): Failed opening '../config.php' for inclusion (include_path='.:/root')
This is confusing to me because the warnings make it seem like I'm doing everything correctly - the include path is /root, and it's looking for file ../config.php (/config.php), which exists. Can someone clear this up for me? Note that using absolute paths is not an option for me, due to deploying to a production server that I have no access to.
Ubuntu/Apache
You could always include it using __DIR__:
include(dirname(__DIR__).'/config.php');
__DIR__ is a 'magical constant' and returns the directory of the current file without the trailing slash. It's actually an absolute path, you just have to concatenate the file name to __DIR__. In this case, as we need to ascend a directory we use PHP's dirname which ascends the file tree, and from here we can access config.php.
You could set the root path in this method too:
define('ROOT_PATH', dirname(__DIR__) . '/');
in test.php would set your root to be at the /root/ level.
include(ROOT_PATH.'config.php');
Should then work to include the config file from where you want.
While I appreciate you believe absolute paths is not an option, it is a better option than relative paths and updating the PHP include path.
Use absolute paths with an constant you can set based on environment.
if (is_production()) {
define('ROOT_PATH', '/some/production/path');
}
else {
define('ROOT_PATH', '/root');
}
include ROOT_PATH . '/connect.php';
As commented, ROOT_PATH could also be derived from the current path, $_SERVER['DOCUMENT_ROOT'], etc.
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';
....
I am here because my php code keeps giving me this annoying error whenever i include something from a directory , or just including something from a file. The error is originating from includes.php. I later found that you have to add the COMPLETE path to the directory. So I did, but it just keeps giving me the same error.
My code:
include_once (__DIR__."/inc/defines.inc.php");
Note that __DIR__ gets replaced by the files own directory path. The issue here is most likely that the path from the script you include does not match the directory you want to include a file from.
A common practice is to have a file at the root of your project that defines the root path. If you include that config file (or whatever you call it), it is easier for you to include other files.
For example. imagine a project like this:
config.php
foo/bar.php
foo/baz/bat.php
Example content of config.php:
<?php
define('ROOT_PATH', __DIR__);
Now, the content of foo/baz/bat.php could be:
<?php
// Get the config file
include '../../config.php';
// Include the content of foo/bar.php
include ROOT_PATH . '/foo/bar.php';
I have this condition :
a file : /public_html/folderX/test.php has a line : require_once '../functions/sendemail.php'
on the other hand, /public_html/functions/sendemail.php has a line : require_once '../config.php'
config.php loads perfectly in this situation.
the problem occurs when I try to add that functions/sendemail.php on file(s) which not in the folderX, for example :
when I tried to add require_once 'functions/sendemail.php' on public_html/test.php I got this error message :
Warning: require_once(../config-min.php) [function.require-once]: failed to open stream: No such file or directory in public_html/test.php
how to make require_once '../config.php' inside functions/sendemail.php works 'independently' so wherever it's included on any files this 'require_once' problem won't occur anymore.
I tried to change into 'include_once' but still doesn't work.
thanks!
try something like
require_once( dirname(__FILE__).'/../config.php')
Try using __DIR__ to attain the current path of the script.
require_once(__DIR__.'../config.php');
__DIR__ only works on php 5.3
__DIR__
The directory of the file. If used inside an include, the directory of
the included file is returned. This is equivalent to dirname(__FILE__).
This directory name does not have a trailing slash unless it is the root directory.
(Added in PHP 5.3.0.)
I believe the relative path names are biting you here. Relative paths are (to my knowledge) based on the directory of the currently active script. PHP doesn't chdir into a folder when including or requiring files. The best recommendation (in my limited experience) for this kind of thing is to use absolute paths where possible. So something like:
require_once('../config.php');
would become:
require_once('/home/myuser/config.php'); // Or wherever the file really is
The dirname function can help in this situation.
You must understand that PHP changes directory to that of the outermost script. When you use relative paths (e.g. those that begin with ./, ../, or those that do not begin with /), PHP will use the current directory to resolve the relative paths. This causes problem when you copy-paste the include lines in your code. Consider this directory structure:
/index.php
/admin/index.php
/lib/include.php
Assume the two index files contain these lines:
include_once("lib/include.php");
The above line will work when /index.php is called but not when /admin/index.php is called.
The solution is to not copy-paste code, use correct relative file paths in your include calls:
/index.php -> include_once("lib/include.php");
/admin/index.php -> include_once("../lib/include.php");
In my app, I'm using an AJAX call to retrieve information, which requires the inclusion of a db_connect.php file. db_connect.php requires other files for it to work.
If I include db_connect.php from the AJAX file, naturally, errors are returned from includes within the db_connect.php file because db_connect.php's includes are relative to the base directory of my application.
How can I change the working directory to the base directory of the application, so the included files will function properly?
What I've tried is using the chdir function:
echo getcwd() . "<br/>";
chdir("../../");
echo getcwd();
This correctly outputs:
/my/webserver/app/lib/ajax
/my/webserver/app
However, the include errors act like I haven't just changed the directory:
Warning: include_once(functions/clean_string.func.php) [function.include-once]: failed to open stream: No such file or directory in my/webserver/app/lib/ajax/ajax.php on line 8
What am I doing wrong?
Then use absolute paths.
For example in a config file, that resides in base of the app, define a base path that is absolute.
define("BASE_PATH", dirname(__FILE__)); //This now is a ABSOLUTE path to a dir that this file is in.
Then use:
include BASE_PATH . "/dir/dir/file.php";
Then, you just have to include the config file in every script at then top relatively from where you are in the app and then just use BASE_PATH in all other includes.
getcwd() does not return your include path; instead, try something like this:
chdir("../../");
include(getcwd()."/functions/clean_string.func.php");