php include path changing based on file - php

I'm brand new to php and I'm trying to work with some includes in my site and can't quite figure out how to make them all work correctly.
My site structure is as follows
/ROOT/
Config.php
Index.php
/ADMINISTRATION/
Index.php
mustInclude.php
/USERS/
Index.php
If "mustInclude.php" includes "Config.php" and Index.php includes "mustInclude.php" everything works fine, but as soon as I try to include "mustInclude.php" into /USERS/Index.php it breaks because "mustInclude.php" is using a path like include '../config.php'; and that isn't the same relative path for /USERS/Index.php as for /ADMINISTRATION/Index.php
I'm not really sure what to do here.
This is on my local machine for now. Using $_SERVER['DOCUMENT_ROOT'] gives me errors because it outputs my file structure (/Users/James/Sites) rather than my web structure (http://localhost/mysite)
Help?

I suggest defining some kind of "global base path" and deducing the other paths from there. Like,
define('BASE_PATH', '/home/me/');
...
include(BASE_PATH . 'Config.php');
include(BASE_PATH . 'subdirectory/other.php');
and so on. This kind of (semi)absolute paths are less fragile than relative paths containing lots of ../s. (Not to say that there's anything fundamentally wrong with relative paths, but they're harder to get just right and tend to break more easily. If /a includes b/c and b/c includes ../d/e, is that relative to /b/ or relative to /, or does it depend on whether we started from /a vs. called b/c directly? I don't even know. Better just use the absolute paths, they're easy and unambiguous :-).

IMO the best way to include files from anywhere in your application directory structure is to add the root folder of your app to your PHP include path:
<?php
set_include_path(get_include_path().PATH_SEPARATOR."/Users/James/Sites/app_name");
Then, just include files using their paths relative to the application root folder, for example:
<?php
require_once('ADMINISTRATION/USERS/Index.php');

Instead of using '../config.php' try using
dirname(dirname(__FILE__)) . DIRECTORY_SEPARATOR . 'config.php'
This way you will always know that one level above is one level above from the current file.

you can use __FILE__

Related

How to call a file outside public_html within the domain directory using php

I have a domain that has a subdomain. I want to call a file in the subdomain folder but apparently my subdomain folder is outside the public_html directory. Here is what i tried but nothing is happening.The subdomain folder is subdomain.
<?php
include("subdomain/conn.php") // location of the file in the subdomain
?>
It is usually most helpful to include with an absolute path instead of a relative path. There are two typical ways to approach this. This example will work with the following directory structure, as you did not provide yours:
+var
|+www
|+public_html
-index.php
|+subfolder
|somescript.php
|+subdomain
|conn.php
1) In your index.php file, declare a constant corresponding to the absolute path to the public_html directory
define('APPLICATION_BASE', __DIR__ . DIRECTORY_SEPARATOR);
Then later use this as the prefix for all includes, and append the path relative to there:
include APPLICATION_BASE . '../subdomain/conn.php';
This option works well for most general purposes, allowing you to quickly include most any file relative to the front-controller/index file
2) Alternately, if you are not using a uniform index file and do not have a consistent point of reference reliable enough to always be included, you would apply a similar approach and include based on an absolute path from the file including it. This usually indicates you are lacking good application structure, but for a quick and dirty app or legacy code that was not structured with a definitive single point of access, this is often necessary. In the case where you had to include a file from somescript.php, and did not reliably arrive there from index.php, you would probably do something like this:
include __DIR__ . '/../../subdomain/conn.php';
It should be noted that this works in a pinch, but it is far from optimal, and you should try to massage your application toward the first approach if at all possible. Using a consistent point of entry will save you a lot of guesswork later when debugging, as you will know all files are included based on relevance to a single origin directory, and it will keep error messages and logging a lot cleaner and more readable over time, which in turn will save you a lot of time debugging.
I haven't tried it yet but it should work.
$public_htmlUrl = $_SERVER['DOCUMENT_ROOT'];
$outsideUrl = "../".$public_htmlUrl;
$file = outsideUrl."subdomain/conn.php";
include($file);

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

Why would I use dirname(__FILE__) in an include or include_once statement?

I have seen this:
<?php
include( dirname(__FILE__) . DIRECTORY_SEPARATOR . 'my_file.php');
?>
Why would I ever need to do this? Why would I go to the trouble of getting the dirname and then concatenating that with a directory separator, and a new filename?
Is the code above not equivalent to this:
<?php
include( 'my_file.php' );
?>
??
The PHP doc says,
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. The include() construct will emit a warning if it cannot find a file; this is different behavior from require(), which will emit a fatal error.
Let's say I have a (fake) directory structure like:
.../root/
/app
bootstrap.php
/scripts
something/
somescript.php
/public
index.php
Now assume that bootstrap.php has some code included for setting up database connections or some other kind of boostrapping stuff.
Assume you want to include a file in boostrap.php's folder called init.php. Now, to avoid scanning the entire include path with include 'init.php', you could use include './init.php'.
There's a problem though. That ./ will be relative to the script that included bootstrap.php, not bootstrap.php. (Technically speaking, it will be relative to the working directory.)
dirname(__FILE__) allows you to get an absolute path (and thus avoid an include path search) without relying on the working directory being the directory in which bootstrap.php resides.
(Note: since PHP 5.3, you can use __DIR__ in place of dirname(__FILE__).)
Now, why not just use include 'init.php';?
As odd as it is at first though, . is not guaranteed to be in the include path. Sometimes to avoid useless stat()'s people remove it from the include path when they are rarely include files in the same directory (why search the current directory when you know includes are never going to be there?).
Note: About half of this answer is address in a rather old post: What's better of require(dirname(__FILE__).'/'.'myParent.php') than just require('myParent.php')?
I might have even a simpler explanation to this question compared to the accepted answer so I'm going to give it a go: Assume this is the structure of the files and directories of a project:
Project root directory:
file1.php
file3.php
dir1/
file2.php
(dir1 is a directory and file2.php is inside it)
And this is the content of each of the three files above:
//file1.php:
<?php include "dir1/file2.php"
//file2.php:
<?php include "../file3.php"
//file3.php:
<?php echo "Hello, Test!";
Now run file1.php and try to guess what should happen. You might expect to see "Hello, Test!", however, it won't be shown! What you'll get instead will be an error indicating that the file you have requested(file3.php) does not exist!
The reason is that, inside file1.php when you include file2.php, the content of it is getting copied and then pasted back directly into file1.php which is inside the root directory, thus this part "../file3.php" runs from the root directory and thus goes one directory up the root! (and obviously it won't find the file3.php).
Now, what should we do ?!
Relative paths of course have the problem above, so we have to use absolute paths. However, absolute paths have also one problem. If you (for example) copy the root folder (containing your whole project) and paste it in anywhere else on your computer, the paths will be invalid from that point on! And that'll be a REAL MESS!
So we kind of need paths that are both absolute and dynamic(Each file dynamically finds the absolute path of itself wherever we place it)!
The way we do that is by getting help from PHP, and dirname() is the function to go for, which gives the absolute path to the directory in which a file exists in. And each file name could also be easily accessed using the __FILE__ constant. So dirname(__FILE__) would easily give you the absolute (while dynamic!) path to the file we're typing in the above code. Now move your whole project to a new place, or even a new system, and tada! it works!
So now if we turn the project above to this:
//file1.php:
<?php include(dirname(__FILE__)."/dir1/file2.php");
//file2.php:
<?php include(dirname(__FILE__)."/../file3.php");
//file3.php:
<?php echo "Hello, Test!";
if you run it, you'll see the almighty Hello, Test!! (hopefully, if you've not done anything else wrong).
It's also worth mentioning that from PHP5, a nicer way(with regards to readability and preventing eye boilage!) has been provided by PHP as well which is the constant __DIR__ which does exactly the same thing as dirname(__FILE__)!
Hope that helps.
I used this below if this is what you are thinking. It it worked well for me.
<?php
include $_SERVER['DOCUMENT_ROOT']."/head_lib.php";
?>
What I was trying to do was pulla file called /head_lib.php from the root folder. It would not pull anything to build the webpage. The header, footer and other key features in sub directories would never show up. Until I did above it worked like a champ.
If you want code is running on multiple servers with different environments,then we have need
to use dirname(FILE) in an include or include_once statement.
reason is follows.
1. Do not give absolute path to include files on your server.
2. Dynamically calculate the full path like absolute path.
Use a combination of dirname(FILE) and subsequent calls to itself until you reach to the home of your '/myfile.php'.
Then attach this variable that contains the path to your included files.

use absolute or relative path?

in my config.php where i have all constants i set the PATH to a absolute path.
but this means that when i move my application folder i have to change this path.
i wondered if its better to set a relative path, in that way whenever i move my application between production and development folder, i dont have to change it.
how do you guys do when you move between folders?
The best way I've found is to do the following:
define("PATH", realpath(dirname(__FILE__)));
That gives you the directory of the current file. If you do this in your settings/bootstrap/init file, you'll have it available to your application, and it will work for any file system.
__FILE__ is your friend.
define('BASE_PATH', dirname(realpath(__FILE__)));
This will make your scripts more portable.
Include a file like this
include BASE_PATH . 'includes/header.php';
IMO, absolute paths are bad news. Even if you don't plan to move, your hosting provider could move you, like DreamHost recently did to me. I was fine....
But there are 14 references to "path" on their wiki:
http://wiki.dreamhost.com/Server_Moves
I do three things to solve this:
The first is to use paths relative to the current file and include things using dirname(__FILE__).
The second is to use a loader include that all the pages load. This file has one responsibility: to find the include directory, usually via a relative call. So long as this relative relationship stays, it doesn't need changing.
I also like to support custom settings that belong to the installation rather than the codebase. This is done by an include mechanism and overrides a few settings that will be specific for the server the code is on.

How do I set an absolute include path in PHP?

In HTML, I can find a file starting from the web server's root folder by beginning the filepath with "/". Like:
/images/some_image.jpg
I can put that path in any file in any subdirectory, and it will point to the right image.
With PHP, I tried something similar:
include("/includes/header.php");
...but that doesn't work.
I think that that this page is saying that I can set include_path once and after that, it will be assumed. But I don't quite get the syntax. Both examples start with a period, and it says:
Using a . in the include path allows for relative includes as it means the current directory.
Relative includes are exactly what I don't want.
How do I make sure that all my includes point to the root/includes folder? (Bonus: what if I want to place that folder outside the public directory?)
Clarification
My development files are currently being served by XAMPP/Apache. Does that affect the absolute path? (I'm not sure yet what the production server will be.)
Update
I don't know what my problem was here. The include_path thing I referenced above was exactly what I was looking for, and the syntax isn't really confusing. I just tried it and it works great.
One thing that occurs to me is that some people may have thought that "/some/path" was an "absolute path" because they assumed the OS was Linux. This server is Windows, so an absolute path would have to start with the drive name.
Anyway, problem solved! :)
What I do is put a config.php file in my root directory. This file is included by all PHP files in my project. In that config.php file, I then do the following;
define( 'ROOT_DIR', dirname(__FILE__) );
Then in all files, I know what the root of my project is and can do stuff like this
require_once( ROOT_DIR.'/include/functions.php' );
Sorry, no bonus points for getting outside of the public directory ;) This also has the unfortunate side affect that you still need a relative path for finding config.php, but it makes the rest of your includes much easier.
One strategy
I don't know if this is the best way, but it has worked for me.
$root = $_SERVER['DOCUMENT_ROOT'];
include($root."/path/to/file.php");
The include_path setting works like $PATH in unix (there is a similar setting in Windows too).It contains multiple directory names, seperated by colons (:). When you include or require a file, these directories are searched in order, until a match is found or all directories are searched.
So, to make sure that your application always includes from your path if the file exists there, simply put your include dir first in the list of directories.
ini_set("include_path", "/your_include_path:".ini_get("include_path"));
This way, your include directory is searched first, and then the original search path (by default the current directory, and then PEAR). If you have no problem modifying include_path, then this is the solution for you.
There is nothing in include/require that prohibits you from using absolute an path.
so your example
include('/includes/header.php');
should work just fine. Assuming the path and file are corect and have the correct permissions set.
(and thereby allow you to include whatever file you like, in- or outside your document root)
This behaviour is however considered to be a possible security risk. Therefore, the system administrator can set the open_basedir directive.
This directive configures where you can include/require your files from and it might just be your problem.
Some control panels (plesk for example) set this directive to be the same as the document root by default.
as for the '.' syntax:
/home/username/public_html <- absolute path
public_html <- relative path
./public_html <- same as the path above
../username/public_html <- another relative path
However, I usually use a slightly different option:
require_once(__DIR__ . '/Factories/ViewFactory.php');
With this edition, you specify an absolute path, relative to the file that contains the require_once() statement.
Another option is to create a file in the $_SERVER['DOCUMENT_ROOT'] directory with the definition of your absolute path.
For example, if your $_SERVER['DOCUMENT_ROOT'] directory is
C:\wamp\www\
create a file (i.e. my_paths.php) containing this
<?php if(!defined('MY_ABS_PATH')) define('MY_ABS_PATH',$_SERVER['DOCUMENT_ROOT'].'MyProyect/')
Now you only need to include in every file inside your MyProyect folder this file (my_paths.php), so you can user MY_ABS_PATH as an absolute path for MyProject.
Not directly answering your question but something to remember:
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.
from: http://us2.php.net/manual/en/function.include.php#84052
hey all...i had a similar problem with my cms system.
i needed a hard path for some security aspects.
think the best way is like rob wrote. for quick an dirty coding
think this works also..:-)
<?php
$path = getcwd();
$myfile = "/test.inc.php";
/*
getcwd () points to:
/usr/srv/apache/htdocs/myworkingdir (as example)
echo ($path.$myfile);
would return...
/usr/srv/apache/htdocs/myworkingdir/test.inc.php
access outside your working directory is not allowed.
*/
includ_once ($path.$myfile);
//some code
?>
nice day
strtok
I follow Wordpress's example on this one. I go and define a root path, normally the document root, and then go define a bunch of other path's along with that (one for each of my class dirs. IE: database, users, html, etc). Often I will define the root path manually instead of relying on a server variable.
Example
if($_SERVER['SERVERNAME'] == "localhost")
{
define("ABS_PATH", "/path/to/upper/most/directory"); // Manual
}
else
{
define("ABS_PATH, dirname(__FILE__));
// This defines the path as the directory of the containing file, normally a config.php
}
// define other paths...
include(ABS_PATH."/mystuff.php");
Thanks - this is one of 2 links that com up if you google for php apache windows absolute path.
As a newbie to intermed PHP developer I didnt understand why absolute paths on apache windopws systems would be c:\xampp\htdocs (apache document root - XAMPP default) instead of /
thus if in http//localhost/myapp/subfolder1/subfolder2/myfile.php I wanted to include a file from http//localhost/myapp
I would need to specify it as:
include("c:\xampp\htdocs\myapp\includeme.php")
or
include("../../includeme.php")
AND NOT
include("/myapp/includeme.php")
I've come up with a single line of code to set at top of my every php script as to compensate:
<?php if(!$root) for($i=count(explode("/",$_SERVER["PHP_SELF"]));$i>2;$i--) $root .= "../"; ?>
By this building $root to bee "../" steps up in hierarchy from wherever the file is placed.
Whenever I want to include with an absolut path the line will be:
<?php include($root."some/include/directory/file.php"); ?>
I don't really like it, seems as an awkward way to solve it, but it seem to work whatever system php runs on and wherever the file is placed, making it system independent.
To reach files outside the web directory add some more ../ after $root, e.g. $root."../external/file.txt".

Categories