PHP - Relative paths to included and required files - php

Well, i am working with a framework that is composed of a somewhat complex file and directory structure.
in my application, i just need to require a file, like so:
require "framework/mainfile.php";
inside mainfile, it is including other files, like:
include "framework/classes/class1.php";
....
and inside some class files it is including other files in the same way;
what i need is to change the location of the framework files and thus the relative path to the framework files in order to have something like
include "lib/framework/mainfile.php";
but i don't want to look in all the files and change the path in every one of them because i would always have to be doing it again when i change to a new version of the framework.
Is there any way of doing this?

use
set_include_path(implode(PATH_SEPARATOR, array(
realpath('Your/updated/path'),
get_include_path(),
));
so your current include paths will not be effected
and you will not need to make change in all files

You can use __DIR__ to get the absolute path of the directory the current script is in. You can then use:
include __DIR__ . '/classes/class1.php';

Related

Relative URLS across different sub folders

Looking for a way of allowing my links and include URLs etc to work on my local machine correctly as well as on my live site.
I have for example a common.php file which contains my DB connection.
I also have a init.php file which is included on every page and inside that includes the common.php file (among others)
For now, i have used
include './common.php';
However, if i am in a page e.g. web/settings
the ./ points to the settings folder.
What should i be using as a relative URL that will work across the whole site no matter what folder etc?
How about /? It refers to the base, and from there you can use the absolute path:
include "/absolute/path/to/file/common.php";
A relative URL is always affected by the current directory, and you can't make it the same no matter where you are on the site. You need to use absolute paths.
You could use $_SERVER['DOCUMENT_ROOT'] for this.
set_include_path( get_include_path() . PATH_SEPARATOR . $_SERVER['DOCUMENT_ROOT'] );
// Now, you can specify your path relative to your DOCUMENT_ROOT.
include('common.php'); // Assuming your common.php file is in your root path.
You'll find it alot more convenient using namespaces though, so you might want to go down that road.
the quick answer for a path is this.
__DIR__ = current working directory so If you have MVC type architecture ( single point of entry aka front controller, basically everything starts off in one file, typically index.php, and the rest are included ) you can just define a constant like this in that main file.
define( 'BASE_PATH', __DIR__.'/' );
So if you have like this
root
index.php //define basepath
includes :
other.php
template :
temp.php
in other you can just do
include BASE_PATH . 'template/temp.php';
everything will be tied by that one base set in the main index.php file, and as long as the folder i put above as root contains everything you can move that where ever you want because of the dynamic part __DIR__
The long answer is to use a PSR-0 autoloader but that might be a bit overkill.
As a side not if you are on PHP < 5.3 use this instead of __DIR__
dirname(__FILE__)

File path error with forward slash at beginning of path

I have a folder with a bunch of articles that all use the same header and footer, which are in an includes/ folder. I also needed to add another file that is not an article and I therefore do not want it in the folder with the other articles, but instead in the includes/ folder. I still want it to use the same header and footer as the articles though, so naturally I just use a command like
include 'article_header.php';
The error is inside the header, which has include commands inside of it. Because the article_header.php file is built for the articles, the include commands inside of it look like the following:
<?php
include 'includes/article_social_container.php';
include 'includes/article_search_container.php';
include 'includes/membership_container.php';
?>
Since this obviously is not going to work for the file inside the includes/ folder. So I tried using a forward slash and starting from the root directory so it works for any file that uses it.
<?php
include '/root/folder/includes/article_social_container.php';
//other code
?>
However, this does not seem to work. I have had trouble with the forward slash at the beginning of a file path in the past, but it has also worked for me other times.
Also, why wouldn't someone always use a forward slash and start at the root directory, just to keep things safe? It probably is the answer to this question because it seems totally sensible to me unless it was for a similar purpose of the open_basedir() function in php.
Thanks a lot for any help.
Take a look at the __DIR__ magic constant. It resolves to the directory of the script in which it appears. Using this, you only need to use relative paths, for example...
// within the "includes" directory
include __DIR__ . '/article_social_container.php';
Another option is to configure your application's include_path. Say you have a script bootstrap.php in your includes directory with the following...
set_include_path(implode(PATH_SEPARATOR, [
__DIR__, // the "includes" directory
get_include_path()
]));
This will add the includes directory to the top of your include_path stack. You can then simply do the following from any other script...
require_once __DIR__ . '/relative/path/to/includes/bootstrap.php';
include 'article_header.php';
Any included scripts from this point on will have the same include_path configuration so they in turn can simply use...
include 'article_social_container.php';
include 'article_search_container.php';
// etc

PHP: require doesn't work as it should

I have a directory root:
index.php
includes/
template.php
testfile.php
phpFiles/
processInput.php
testfile.php
index.php:
require_once("includes/template.php");
template.php:
require_once("includes/phpFiles/processInput.php")
processInput.php:
require_once("testfile.php")
require_once("../testfile.php")
This code will work when you run index.php, of course it will not work when you run template.php.
As you can see, index.php includes template.php like normal. But in template.php, you have to include like if you are in the directory that index.php is in. But then, in processInput.php, you include as if you are in the directory that processInput.php is in.
Why is this happening, and how can I fix it so that the include path is always the directory of the file that the require is done in? The second included file have the same include path as the requested file, but the next one does not.
Thanks for your help!
EDIT: The strange thing is that I've included classes in a class folder. And it included other files as it is supposed to, even though the paths are relative. WHY does this happen, and how can I fix it?
VERY IMPORTANT EDIT: I just realized that all this is because in my example, the inclusion in includes/phpFiles/processInput.php includes a file in the same directory: require_once("file in same dir.php"); This is the reason. If you are including a file with out specifying anything more than the filename, the include_path is actually the dir where the file the require is written in is in. Can anyone confirm this?
Use an absolute path.
require_once($_SERVER['DOCUMENT_ROOT']."/includes/phpFiles/processInput.php");
Use a similar form for all your required files and they will work no matter where you are.
You can do this in a few ways, amongst others:
Use set_include_path to control the directories from where to perform require() calls.
Define a common absolute base path in a constant that you define in index.php and use that in every require() statement (e.g. require(BASEPATH . '/includes/template.php')).
Use relative paths everywhere and leverage dirname(__FILE__) or __DIR__ to turn them into absolute paths. For instance: require(__DIR__ . '/phpFiles/processInput.php');
By default, the current working directory is used in the include path; you can verify this by inspecting the output of get_include_path(). However, this is not relative to where the include() is made from; it's relative to the main executing script.
You're using relative paths. You need to use absolute paths: $_SERVER['DOCUMENT_ROOT'].
When you include/require, you are basically temporarily moving all code from one file, to another.
so if file1.php (which is located in root) contains:
require("folder/file.php");
and you include file1.php in file2.php (which is in a different location (say folder directory for example):
file2.php:
require("../file1.php");
Now all of file1.php code is in file2.php. So file2.php will look like this:
require("../file1.php");
require("folder/file.php");//but because file2.php is already in the `folder` directory, this path does not exist...
index.php:
require_once("includes/template.php");
template.php:
require_once("includes/phpFiles/processInput.php")
Your directory structure is off. The file inclusion is being seen from the file you're using it from. So, "template.php" is looking for an "includes/" folder in its current folder (/includes/).
As others are saying, use absolute paths, which will make sure you're always going at it from the file system root, or use:
require_once("phpFiles/processInput.php")
In your template.php file (which is far more likely to break if you ever move things around, which is why others all recommend using absolute paths from the file system root).
BTW, if you're using "index.php" as some kind of framework system, you can consider defining a variable that stores the address of common files such as:
define('APPLICATION_PATH', realpath(dirname(__FILE__));
define('PHPFILES_PATH', APPLICAITON_PATH . '/includes/phpFiles/');

Trouble with / vs ./ vs ../ and absolute and relative paths

I have many PHP files in
/
/client/
/user/
/config/
etc...
I want all my files to include /user/codestart.php. (Lots of functions etc)
Therefore:
All files in / have include("./user/codestart.php");
All files in /user/ have include("codestart.php");
All files in /client/ have include("../user/codestart.php");
The problem is that /user/codestart.php has include("../config/config.php"); (The MySQL ID and password)
When a file in / runs, such as /index.php, it includes ./user/codestart.php.
Then /user/codestart.php includes ../config/config.php, but it cannot see it, because it thinks it is calling it from /, instead of from /user/.
If I change
include("../config/config.php") to be
include("./config/config.php")
that fixes it for / files, but breaks it for/user/ and/client/ files.
Bottom line is that when one PHP file includes another file, PHP thinks it is operating from the location of the original file, not the calling file.
I need to use relative paths, not absolute paths. Absolute paths will not work in my situation.
Is there any way to solve this?
One way to deal with this is this:
Have a central configuration file (e.g. /myproject/config/bootstrap.php
In that configuration file, define a global root for your application. E.g.
define("APP_ROOT", realpath(dirname(__FILE__)."/.."));
Include that configuration file in every PHP file. E.g.
include("../config/bootstrap.php");
Whenever you reference some other file, use
include APP_ROOT."/includes/somefile.php";
Voilá - you have a fixed point in space (APP_ROOT) and can reference everything relative to that, no matter which directory you are in.
If you want to do it this way I suggest you make a seperate file for all your includes which is in a fixed dir, the root for example.
Then you reliably include all the files from there using
include __DIR__.'path/relative/from/includefile.php'
If your php verion is lower than 5.3 you should use dirname(__FILE__) instead of __DIR__ as mentioned by RiaD
You might like this php.net page
You can use relative paths in conjuntion with dirname(__FILE__)
So in your codestart file write:
require_once dirname(__FILE__).'/../config/config.php';
You can set the path that PHP uses to look for files, so that it contains all your folders. In index.php:
$folders = implode(PATH_SEPARATOR, array('user', 'config'));
set_include_path(get_include_path().PATH_SEPARATOR.$folders);
Then you can just do:
include("codestart.php");
and:
include("config.php");
This will work for index.php and all files that index.php includes.
use absolute paths. to get path to your root directory use $_SERVER['DOCUMENT_ROOT'], ex.
include $_SERVER['DOCUMENT_ROOT'].'/user/codestart.php';
include $_SERVER['DOCUMENT_ROOT'].'/config/config.php';
It save you from absolute paths' problems.

PHP how to find application root?

I'm having problems with my include files. I don't seem to be able to figure out how to construct my URLs when I use require_once('somefile.php'). If I try to use an include file in more than one place where the directory structures are different, I get an error that the include file cannot be found.
In asp.net, to get my application root path, I can use ~/directory/file.aspx. The tild forward slash always knows that I am referencing from my website root and find the file no matter where the request comes from within my website. It always refers back to the root and looks for the file from there.
QUESTION: How can I get the root path of my site? How can I do this so I can reuse my include files from anywhere within my site? Do I have to use absolute paths in my URLs?
Thank you!
There is $_SERVER['DOCUMENT_ROOT'] that should have the root path to your web server.
Edit: If you look at most major php programs. When using the installer, you usually enter in the full path to the the application folder. The installer will just put that in a config file that is included in the entire application. One option is to use an auto prepend file to set the variable. another option is to just include_once() the config file on every page you need it. Last option I would suggest is to write you application using bootstrapping which is where you funnel all requests through one file (usually with url_rewrite). This allows you to easily set/include config variables in one spot and have them be available throughout all the scripts.
I usually store config.php file in ROOT directory, and in config.php I write:
define('ROOT_DIR', __DIR__);
And then just use ROOT_DIR constant in all other scripts.
Using $_SERVER['DOCUMENT_ROOT'] is not very good because:
It's not always matching ROOT_DIR
This variable is not available in CGI mode (e.x. if you run your scripts by CRON)
It's nice to be able to use the same code at the top of every script and know that your page will load properly, even if you are in a subdirectory. I use this, which relies on you knowing what your root directory is called (typically, 'htdocs' or 'public_html':
defined('SITEROOT') or define('SITEROOT', substr($_SERVER['DOCUMENT_ROOT'], 0, strrpos($_SERVER['DOCUMENT_ROOT'], 'public_html')) . 'public_html');
With SITEROOT defined consistently, you can then access a config file and/or page components without adapting paths on a script-by-script basis e.g. to a config file stored outside your root folder:
require_once SITEROOT . "/../config.php";
You should use the built in magic constants to find files. __FILE__ and __DIR__. If you are on PHP < 5.3 you should use dirname(__FILE__)
E.g.
require_once __DIR__.'/../../include_me.php';
$_SERVER['DOCUMENT_ROOT'] is not always guaranteed to return what you would expect.
Define it in a config file somewhere.
Assuming you're using an MVC style where everything gets routed through a single index.php then
realpath('.');
Will show you the path to the current working directory (i.e where index.php is)
So then you can define this as
define('PROJECT_ROOT', realpath('.'));
If it's not MVC and you need it to work for files in subfolders then you can just hard code it in a config file
define('PROJECT_ROOT', 'C:/wamp/www/mysite');
Then when including something you can do;
include PROJECT_ROOT . '/path/to/include.php';
You could alternativly set the base directory in your .htaccess file
SetEnv BASE_PATH C:/wamp/www/mysite/
Then in PHP you can reference it with $_SERVER['BASE_PATH']
Try this:
$_SERVER['DOCUMENT_ROOT']

Categories