In PHP, is there a way for a page to determine where it is in a site's directory structure?
November 4, 2005 7:33 AM   Subscribe

In PHP, is there a way for a page to determine where it is in a site's directory structure? I'm new to PHP, and I want to create an include that will contain my global navigation. The problem I'm having is that I can't figure out how to do that with relative URLs since the include could be written to a page in any of several directory levels. I'm sure this is a solved problem, there's probably even a built in function, but danged if I can find it. So 1, How do I have PHP build my relative URLs based on where they come up in a site's directory path? And 2, where do I go in the future to find this kind of stuff out for myself?
posted by willnot to Computers & Internet (21 answers total)
 
PHP System Variables... See PATH_INFO, and PATH_TRANSLATED
posted by twiggy at 7:44 AM on November 4, 2005


Take a look at the Predefined variables list.

$_SESSION['SERVER_NAME'] might be what you're looking for but it depends on your web hosting configuration (virtual hosts etc.).
posted by purephase at 7:45 AM on November 4, 2005


Oh, I just googled for PHP system variables, by the way. I don't even code in PHP :-) I'd suggest looking at books on PHP though. Search slashdot for reviews and find a good one, or check Amazon and search for highly reviewed books. You'll probably never sit and read one cover to cover, but more use it as a dictionary/encyclopedia.
posted by twiggy at 7:46 AM on November 4, 2005


purephase: not to poo-poo your comment, but he's looking for directory paths, not the hostname that is being accessed.

I'm only commenting so that when he reads these, he realizes what it is you've sent him :-)

the SERVER_NAME variable is useful when hosting many sites with the same code. If you wanted to host blah1.com and blah2.com from a single set/instance of scripts (stored in the same directory, with multiple sites pointing to it) - then SERVER_NAME would tell you which site is being accessed - blah1.com? or blah2.com?
posted by twiggy at 7:49 AM on November 4, 2005


Oops, typo. Change the $_SESSION to $_SERVER. ;)
posted by purephase at 7:50 AM on November 4, 2005


If it's the directory structure from the webserver, then $_SERVER['DOCUMENT_ROOT'] will give you the root folder of your website.
posted by purephase at 7:52 AM on November 4, 2005


$dirpath = dirname(__FILE__);

will return the path of the current file. Note that if you have included a file from another directory with this line in it, $dirpath will contain the directory of that included file and not that of the parent script.
posted by tumble at 7:57 AM on November 4, 2005


Why would you not use absolute paths? This is a perfect example of what they're good for.

Everyone's comments so far have been ways for PHP to write absolutely pathed urls, not relative urls. Doing actual dynamically-generate relative urls would be very convoluted and probably not that useful.
posted by 4easypayments at 8:04 AM on November 4, 2005


ok, on completely reading the question:
http://www.php.net/tips.php has some quick reference tips.

If you are familiar with IRC, Freenode has a very helpful #PHP channel.

a file with just
<?php phpinfo(); ?>
will help you find all of the available script variables.

$_SERVER['PHP_SELF'] will contain the url from the web root of the currently running file. You can then trim this or manipulate the string to get the filename. I tend to stay away from ereg unless I need them, and so I might do this:

<?php
$dirpath = substr($_SERVER['PHP_SELF'],0,strrpos($_SERVER['PHP_SELF'],'/'));
?>

This removes everything from the last slash.
posted by tumble at 8:19 AM on November 4, 2005


$_SERVER["PHP_SELF"] may be what you're looking for.

For future reference, The PHP Manual rocks.
posted by polyglot at 8:21 AM on November 4, 2005


Response by poster: I thought about using absolute paths, but how do you handle the switch from a Development to Production environment? Do you have to modify your paths before uploading, or is there a way to have an absolute path that works in either a local or published state?

$dirpath = dirname(__FILE__);

...seems to work but it looks like that provides the server directory path rather than the site directory. I'm sure I can work with that though if I think about it hard enough.

I tried :

$dirpath = getenv(PATH_INFO);

-- AND --

$dirpath = $_SERVER['PATH_INFO'];

Both of those seem to return a NULL value when I echo them though.
posted by willnot at 8:23 AM on November 4, 2005


Response by poster: And, just to be clear about what I'm looking for, say I have a global navigation link to site.com/about.php.

If, my include gets written into site.com/FAQ.php, the the path would be "about.php", but if my include gets written into site.com/profile/index.php, then the path would need to be "../about.php".

I'm trying to create the code in a global include that would construct those paths based on where the page they get written to will exist in the site structure.

I would just make the path "site.com/about.php", but then none of those links will work on a local version of the site.
posted by willnot at 8:32 AM on November 4, 2005


Best answer: You don't need php, you just need to use paths relative to the document root. Don't use relative urls with the dots. /profile/index.php could be used in the href of a link anywhere on the site, and it will always link to the corect location.
posted by tumble at 8:37 AM on November 4, 2005


Best answer: Erm... maybe I'm missing something here but why don't you start your links with a "/"?

"/about.php" will always take you to site.com/about.php, no matter where the linking page is located. Even if it's "site.com/this/is/a/subdirectory/include.php".

You've got apache set up locally, right? So your local site should be the same as your production site.
posted by blag at 8:44 AM on November 4, 2005


Yeah. That.
posted by blag at 8:44 AM on November 4, 2005


Best answer: If, my include gets written into site.com/FAQ.php, the the path would be "about.php", but if my include gets written into site.com/profile/index.php, then the path would need to be "../about.php".

Set up your links like this: "/about.php". That will work regardless of where in your site it is executing from. If your link starts with a slash, the hostname is automatically prepended. So it's an absolute URL, with an indefinite hostname. You do not want a relative URL - the include is in only one place!
posted by jellicle at 8:45 AM on November 4, 2005


Response by poster: Well, that was easy. For some reason, I rever realized that.

Thanks all.
posted by willnot at 8:57 AM on November 4, 2005


In most of my sites, I do the following:

Use the base href to define the root referral path:
<base href="<?=$_SERVER['SERVER_NAME']?>">

Then, in any navigation etc. I use relative pathing off the defined base:

So, in your example, your link to about.php would always be:
<a href="./about.php">About</a>

It's not perfect, but it's served me well.
posted by purephase at 8:58 AM on November 4, 2005


The phrase we're looking for is "root-relative" links.

Relative links only work from one level in the directory structure.

Absolute links work from anywhere on the internet.

Root-relative links start from the top level of the web server and work from there.

Which, of course, makes them perfect for moving from development to production versions of a site.
posted by AmbroseChapel at 1:12 PM on November 4, 2005


Best answer: Depending on your dev vs production environment, the /about.php strategy may not work. For example we have one dev server that we use for several production servers. And in that case the document root on the dev server may not match the document root on the production server.

We've found it can be helpful to have a config variable set which defines the document root, rather than just assuming it's /.

So on the dev server our config will define:
$RootPath = '/intranet/';

And on the prod server our config will define:
$RootPath = '/';

Then in the code we'll use things like:
echo "href=" . $RootPath . "about.php";
posted by y6y6y6 at 2:14 PM on November 4, 2005


Response by poster: Thank you y6y6y6. That solved my next challenge.
posted by willnot at 4:02 PM on November 4, 2005


« Older Who are Sweeney and Mrs. Porter?   |   Need Wicked Awesome Screensaver Newer »
This thread is closed to new comments.