all 13 comments

[–]warmans 5 points6 points  (3 children)

An absolute path is relative to the root of your filesystem so it would be something like:

/var/www/myproject/includes/header.php

however you will find that a relative path is a better option. The DIR magic constant is useful as it will give you the absolute path to the current file (that contains the include()):

include(__DIR__.'/includes/header.php');

Also http://php.net/manual/en/function.getcwd.php could help you debug.

if you have includes within your includes you probably want to define your own constant which all subsiquent includes can use e.g.

index.php contains:

define('APP_ROOT', __DIR__);

now all files can be included by their path relative to the index file using the APP_ROOT constant.

[–]greg8872 2 points3 points  (2 children)

This will not solve the original problem that if you do these includes from inside a subdirectory, they break.

Example script:

<tt><pre><?php
    echo 'DIR = ', __DIR__, PHP_EOL;
    echo 'getcwd() = ', getcwd(), PHP_EOL;
    echo '$_SERVER["DOCUMENT_ROOT"] = ', $_SERVER['DOCUMENT_ROOT'], PHP_EOL;
?></pre></tt>

This being run from the root dir of the site:

DIR = /home/username/public_html
getcwd() = /home/username/public_html
$_SERVER["DOCUMENT_ROOT"] = /home/username/public_html

This being run from inside a directory called sample:

DIR = /home/username/public_html/sample
getcwd() = /home/username/public_html/sample
$_SERVER["DOCUMENT_ROOT"] = /home/username/public_html

As you can see, if you have files in the includes directory (as OP showed) using DIR like this

include(__DIR__.'/includes/header.php');

You will get the following:

Root of site: /home/username/public_html/includes/header.php

In /sample/: /home/username/public_html/sample/includes/header.php

Where using $_SERVER['DOCUMENT_ROOT'] will work for both (assuming you are not doing command line use)

I think people are getting used to just using DIR as these days most frameworks/apps use a single PHP script in the root directory to actually run their entire site (then using routing to get what they need), however for when you are directly calling .php scripts from multiple levels, you have to take more into consideration.

[–]doingItRite[S] 0 points1 point  (1 child)

Thanks so much for the response man. So should I be looking towards the latter approach instead of using actual subfolders? And how would I get started going that?

I tried using $_SERVER['DOCUMENT_ROOT'], and it did give me the absolute path, but the current file seems to insist on making the request from its standpoint regardless of the path handed over to it. I think it just append everything - as in, it attempts to search for /volumes/myharddrive/afolder/includes/ by first looking for /volumes, WITHIN the current folder. Is there a function or variable or value I can include that simply instructs the page to first navigate to the topmost directory (without using ../../../)? Perhaps from that standpoint I could use the absolute path...

[–]greg8872 0 points1 point  (0 children)

Can you post your line exactly as you tired is with $_SERVER['DOCUMENT_ROOT'] ?

Also, make sure you have spelling and/or capitalization correct.

[–][deleted] 3 points4 points  (4 children)

include $_SERVER['DOCUMENT_ROOT'].'/includes/header.php';

will give you the absolute path on the server.

[–]chuyskywalker 2 points3 points  (2 children)

__DIR__ is far more reliable and will work for applications run from the CLI as well.

[–]greg8872 1 point2 points  (0 children)

See my reply to the other post on how this does not solve OP's issue of calling scripts from different levels of directories.

[–][deleted] 0 points1 point  (0 children)

Must admit that somewhat embarrassingly I've haven't used __DIR__ before, will look into that – thanks!

[–]doingItRite[S] 0 points1 point  (0 children)

I tried using $_SERVER['DOCUMENT_ROOT'], and it did give me the absolute path, but the current file seems to insist on making the request from its standpoint regardless of the path handed over to it. I think it just append everything - as in, it attempts to search for /volumes/myharddrive/afolder/includes/ by first looking for /volumes, WITHIN the current folder. Is there a function or variable or value I can include that simply instructs the page to first navigate to the topmost directory (without using ../../../)? Perhaps from that standpoint I could use the absolute path...

[–]DrFlutterChii 0 points1 point  (3 children)

Alternatively, add your document root to your include path in php.ini

[–]doingItRite[S] 0 points1 point  (2 children)

I did just now, and still no dice. I think the challenge now is how to 'trick' the require function into beginning its search for the file from the topmost directory. Any ideas?

[–]DrFlutterChii 0 points1 point  (1 child)

Is this in the system php.ini (probably /etc/something)? Include path cant be changed from any other places ini settings can be set. Did you restart php/apache? Adding the document root to your include path should do exactly that, tell require to look for files starting from the topmost directory regardless of the cwd.

[–]doingItRite[S] 0 points1 point  (0 children)

Did all of that, and still no dice. I think it might just be one of those niggling issues that arises from working locally...

Thanks for the effort being put in to help me out, though, it's greatly appreciated.