PHP including files - php

What's the difference between
$_SERVER['DOCUMENT_ROOT'];
and
dirname(__FILE__);
I wonder what's the difference because when I 'echo' them, they're returning same path. Which do you prefer should I use and why?
Thanks!

Both are different
_FILE_
The full path and filename of the file. If used inside an include, the name of the included file is returned. Since PHP 4.0.2, FILE always contains an absolute path with symlinks resolved whereas in older versions it contained relative path under some circumstances.
source : PHP magic constants
Let's said, your document is /var/www,
and your index page is /var/www/index.php
dirname(__FILE__) == $_SERVER['DOCUMENT_ROOT'];
But if you drill-down to sub-folder like /var/www/posts/index.php
dirname(__FILE__) != $_SERVER['DOCUMENT_ROOT'];
/var/www/posts != /var/www
The use of $_SERVER['DOCUMENT_ROOT'] is more appropriate in this case.

__FILE__ always points to the current file path, and $_SERVER['DOCUMENT_ROOT'] points to the document root path ;-)
I prefer first one, as it is more semantic.
If you will try to compare the values of the files, that are located not in your docroot - then you'll get different values.

The former one is a root folder for the HTTP server (or VirtualHost) and it is a server setting.
The latter is the folder containing the current file.
The usage is entirely based on requirements in my opinion.

You would normally use $_SERVER['DOCUMENT_ROOT'] when you want to reference your website's root folder from any where within your website or web application.
You will find using dirname(__FILE__) handy if you were including a file, that then needed to include some more files from the same directory. I use this in my PHP wrapper for the Dribbble API
class Dribbble {
function __construct() {
require_once(dirname(__FILE__) . '/base.php');
require_once(dirname(__FILE__) . '/shot.php');
require_once(dirname(__FILE__) . '/player.php');
}
}
This means I can just include dribbble.php from any where in my website or web application and not worry about also including base.php, shot.php, and player.php at the same time.

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__)

Require file including variable

I am currently using the following code to include a file in my webpage:
require_once $_SERVER['DOCUMENT_ROOT'] . '/include/file.php';
However, I have now edited my system so I input the URL into a data file in the root which makes other parts of my site function and allows me to use different directories.
In short, I am using a splash page on a website, where the root is now /directory rather than in the root, thus the URL in my data file is http://www.domain.com/directory.
So, what I need to work out is how to point this line at the directory using the variable from the data file which contains the URL
So $_SERVER['DOCUMENT_ROOT'] becomes irrelevant because I need to grab the data from the variable in the data file which is NOT in the root anymore.
It needs to be something like:
require_once (variable from file a few directories back) + absolute path to file;
I want this line of code to be future-proof too, if I need to build a site using a different directory then the root.
I hope that makes sense!
Create a SITE_ROOT and use that instead. That way, it will work with any directory change.
define('SITE_BASE', '/directory/');
define('SITE_ROOT', $_SERVER['DOCUMENT_ROOT'] . SITE_BASE);
You can then use SITE_BASE for creating your URIs:
link
and SITE_ROOT for accessing files on the system:
require_once SITE_ROOT . 'include/file.php';
Have you considered setting include_path in your php.ini file? For instance, my own php.ini file has include_path = ".:/path/to/web/root", which allows me to not worry about where my files are when including them.
In your case, you would want to set it to include_path = ".:/path/to/web/root/directory". If you don't know the path to the web root, just run echo $_SERVER['DOCUMENT_ROOT']; to find it.
This solution is "future-proof", as you only need to change that php.ini value and everything falls into place.

php question include an included file

I got a problem about including a included file in PHP.
Project
functions(folder) has a.php
xml(folder) has b.xml
index.php
This is my project structure(sorry about that, I can't post images).
I try to use "index.php" to include "a.php" while "a.php" is using "b.xml"
this is what i did on XAMPP and it works perfectly:
in index.php I wrote: include 'functions/a.php';
in a.php I wrote: $xml->load('xml/b.xml');
However if I copy these to my Uni's apache server, it can't open this b.xml.
This is not permission because when i change to absolute path it works...
Thank you guys in advance:-)
in a.php you should refer to ../xml/b.xml if you use include
thing is, it depeneds on when $xml->load() is defined. if it's your own code then put the path relative to the definition. otherwise "../xml/b.xml" should work.
you can always to $_SERVER['DOCUMENT_ROOT'], but i myself like defining directories as constants (with absolute path) and using them around the project.
define('DIR_ROOT', $_SERVER['DOCUMENT_ROOT'] . '/');
define('DIR_FUNCTIONS', DIR_ROOT . 'functions/');
define('DIR_XML', DIR_ROOT . 'xml/');
Try using set_include_path() to set the include path to your application's root directory; then you should be able to include files relative to this path.
It's always better to use absolute paths, even if you have to construct it (e.g. $XML_PATH = $PATH_TO_BASE . 'xml/b.xml'; )
If you can't do that, you should add xml's parent to your path.

Relative include files

I have a file
workers/activity/bulk_action.php which includes a file
include('../../classes/aclass.php');
Inside aclass.php it does:
include ('../tcpdf/config/lang/eng.php');
It seems that the include in the second file is using the first files working directory instead of being relative to itself, resulting in an error. How does this work?
You can adapt the second include with:
include (__DIR__.'/../tcpdf/config/lang/eng.php');
The magic constant __DIR__ refers to the current .php file, and by appending the relative path after that, will lead to the correct location.
But it only works since PHP5.3 and you would have to use the dirname(__FILE__) construct instead if you need compatibility to older setups.
You would be way better off by setting a proper value to the include_path and then use paths relative to this directory.
set_include_path(
get_include_path() .
PATH_SEPARATOR .
realpath(__DIR__ . '/your/lib')
);
include 'tcpdf/config/lang/eng.php';
include 'classes/aclass.php';
I also suggest you take a look at autoloading. This will make file includes obsolete.
Files are included based on the file path given or, if none is given, the include_path specified. If the file isn't found in the include_path, include() will finally check in the calling script's own directory and the current working directory before failing.
You can use dirname(__FILE__) to get a path to the directory where the currently executed script resides:
include(dirname(dirname(__FILE__)) . '/tcpdf/config/lang/eng.php');
(since PHP 5.3, you can use __DIR__)
Or, define a constant in the first file that points to the root directory and use it in your includes.

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