Forum Moderators: phranque

Message Too Old, No Replies

how to configure Apache so PHP looks for files from Web root

PHP now understands "/" as server root

         

zollerwagner

4:42 am on Apr 7, 2004 (gmt 0)

10+ Year Member



I'm working with a new Web host. He's got his server set up so if I include a php file in another php file, the "/" refers to the server root rather than the document root or my Web root. (It's a virtual server.)

The admin doesn't know how to set up the server so I can write:

require("/scriptsFolder/myScript.php");

with "/" being my Web root.

At this point the set up looks like this:

<VirtualHost *>
ServerAdmin admin@host'sDomain.com
DocumentRoot /home/sites/myDomain.com/myTestDirectory
ServerName myTestDirectory.myDomain.com
ServerAlias www.myTestDirectory.myDomain.com
ErrorLog logs/anotherDirectory.myDomain.com-error_log
<Directory /home/sites/myDomain.com/myTestDirectory>
AllowOverride All
</Directory>
</VirtualHost>

I should explain that we have been trying this on a separate folder, so I can pretest site changes by going to: myTestDirectory.myDomain.com

I'd eventually like it to work on the regular site, too.

Any tips?

jamesa

9:03 am on Apr 7, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



That's how it should work. There are instances when you'd want to access documents outside of your document root.

The best way to do it is:

require($_SERVER["DOCUMENT_ROOT"] . "/scriptsFolder/myScript.php");

And you'll have the added benefit of portability.

zollerwagner

4:18 pm on Apr 7, 2004 (gmt 0)

10+ Year Member



Ah, so that would make it easier to go below Web root to keep some files secure. Good idea.

Thanks Jamesa.

zollerwagner

4:44 pm on Apr 7, 2004 (gmt 0)

10+ Year Member



What would be the best way to address a folder that is below web root? Let's say we call it "hiddenFolder".

I could write:
/home/sites/myDomain.com/hiddenFolder/file.php

But there must be another way to write this more succinctly.

jamesa

5:13 pm on Apr 7, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



That's how I do it. Though I usually store it in a variable so I only need to change it once.

$hiddenPath = '/home/sites/myDomain.com/hiddenFolder/';
include ("$hiddenPath/file.php");

isitreal

5:29 pm on Apr 7, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Add this to your httpd.conf or to your .htaccess file:

php_value include_path ".:/usr/www/yourdomainfolder/includes"

That's all you have to do, make the path to wherever you want it, from the server root, it's usually recommended to not have your includes in the same folder as your main site.

then all you have to do is put this:

include("yourfilename.inc");
anywhere on the site, apache takes care of the rest for you.

zollerwagner

5:47 pm on Apr 7, 2004 (gmt 0)

10+ Year Member



Those are both excellent ideas! Thanks so much!

zollerwagner

6:13 pm on Apr 7, 2004 (gmt 0)

10+ Year Member



One question. In Jamesa's suggestion the $hiddenPath ends with a slash and the include has another slash. Doesn't it seem as though there'd be an extra slash? Maybe the extra slash gets ignored. It seems to work.

in $hiddenPath = '/home/sites/myDomain.com/hiddenFolder/';
include ("$hiddenPath/file.php");

The other idea by Isitreal (defining in .htaccess where php includes would be stored) only works if they're all stored in the same place, but there could be another level of folders in addition to the base includes location, I assume. And all of this could all be below Web root,right? Maybe that's an advantage.

Both are great ideas.

isitreal

6:33 pm on Apr 7, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



I thought this would be clear, but I guess it wasn't.

When you set the path to the include directoy, that's all you are doing. You can have as many folders inside that directory as you want.

When you use 'include(..)' all that happens is that the search for the path starts in the include directory.

So you can have whatever directory structure inside you include directory you want, the example I listed was just the simplest one, a file at the root of the include directory.

eg>
/www/users/your_main_domain_folder/includes

is one directory,
/www/users/your_main_domain_folder/site
is your actual website directory.

includes can have any subdirectories you want, like
includes
-programs
-data
--html
-misc

then your include statement for a file in 'programs' would be this:
include('programs/your_file.inc');

Since 'includes' is your root directory as as far as the php include/require statements are concerned, you don't put a '/' before the first folder, since that would take you to the server root, eg

include('/programs/your_file_name.inc');

would not work, since it's looking for the file at the server root, not the root of the include folder.

this is the easiest way to set include paths in Apache, that's why they have that php_value include_path syntax.

It also makes it easy to set up sites on your development server, since all you have to do is set up the include path for your system, and you can have the include folder whereever you want on either the host server or on your developement server.

zollerwagner

7:10 pm on Apr 7, 2004 (gmt 0)

10+ Year Member



That's very clear. Thanks, Isitreal.

I like the fact that it's easy to move from the development area to the live area with one simple change.

If the require("file"); doesn't have a "/", is it an absolute path because the server fills in the rest?

That would be important if the site has directories for different areas, like a directory for the about us pages:
aboutUs/index.php

-----

I have php pages that have includes that are really just ssi's for page layout (navigation, header, etc.), they reside in a folder above Web root(i.e., Web visible). It looks like I can use both methods suggested.

I.e, the actual php includes, stored in hidden folders, can be done with IsitReal's method and the basic html ssi's would be done with Jamesa's method and stored in a folder in the Web root.

Thanks again!

zollerwagner

7:27 pm on Apr 7, 2004 (gmt 0)

10+ Year Member



My testing indicates that Jamesa's example may have a small error.

in $hiddenPath = '/home/sites/myDomain.com/hiddenFolder/';
include ("$hiddenPath/file.php");

should not have the last "/" in the $hiddenPath definition. Interestingly it seems to work anyway, but the resulting path would have two slashes together, like this:
/home/sites/myDomain.com/hiddenFolder//file.php

isitreal

8:21 pm on Apr 7, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



This might just be my preference, but I find it's easier to maintain my includes if they are all in the same directory, with reasonably clear sub directories, that way I'm always only using one method, and one path, on all pages, and I can ftp directly into my includes directory to update any includes there, whether page chunks like headers or programming files or data files.

this way I don't have to keep track of where everything is for different sites, it took me a while to see the advantage of that, but it gets easier to see if for example you start running multiple sites on the server, then you could have directories like this:

includes
-programs
-data
-site1
--navigation
--html
-site2
--navigation
--html

and so on

this also makes it easier to maintain the webhoster files and the development files, since all of them are in the 'includes' folder.

But again, whatever works best for you is probably a good way to go, that's just something I started noticing I ended up doing after a while on all my sites.

The real advantage with pulling everything off the page in terms of the paths is that you can change the location of your include folder anytime you want by just editing a single line of code in apache or htaccess, that's very convenient over the long term.

zollerwagner

9:54 pm on Apr 7, 2004 (gmt 0)

10+ Year Member



Are site1 and site 2 are the real site and the test site?

To do it the way you do, are all of your includes necessarily done with PHP's require() function?

The way the host I'm working with has his sites set up is that the html ssi includes refer to Web root (and php_value include path doesn't change that). Since all of the pages in this site are php pages, that isn't an issue here, but it is in other sites I work on.

isitreal

10:06 pm on Apr 7, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Oh, I missed that. If you are using actual ServerSideIncludes, that is, if your pages are shtml, not html/php, setting the include path for php won't affect that, I thought you were using the terms ssi loosely to just refer to php included html files.

I generally don't use require, since if a file load fails the whole page execution fails. Require is supposed to be used for loading primary library functions, or so Rasmus Lerdorf, PHP's author, says.

Include is what you usually want to use. Personally, I can't think of any reason to use actual SSI when you are also using PHP, although I'm not sure that's what you are doing. If that's what you are doing I'd just switch it all over. From what I understand, you can't mix ssi and php pages, ie, you can't run php on a ssi page.

The example I gave, site1 and site2, it's just an example, you might have shared library files and data for all your sites, and specific html and navigation for site1 and site2, etc.

It's not the only way to do it, just one way.

If you are only running one site, and will always only run one site, then this wouldn't apply in your case.

zollerwagner

10:20 pm on Apr 7, 2004 (gmt 0)

10+ Year Member



In this site, there are no html ssi includes. And you're quite right, you can't (at least I've never seen it work) use ssi includes with php-parsed pages. They don't get included and you can see the commented include lines in the source.

I hadn't considered using php's include instead of require, but what you're saying makes very good sense. Back to the code.... Thanks, again!

isitreal

10:34 pm on Apr 7, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Using include will give more meaningful error printouts in general, since the page will continue loading in many cases, and just print out the errors in questions.

Anyway, have fun, it sounds like you're ready to go.

If you don't know this one yet, it will also make your life easier, also added to httpd.conf or .htaccess:

AddType application/x-httpd-php .htm .html

that makes all .htm and .html pages run as php, you don't have to give them the php extension.

That really helps if you are switching over a site or a page to php and don't want to break links or lose search engine positioning.

jamesa

11:49 pm on Apr 7, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



>> should not have the last "/" in the $hiddenPath definition

Yes, thanks for catching that :)

zollerwagner

9:36 am on Apr 8, 2004 (gmt 0)

10+ Year Member



Yes, I figure that visitors will be a lot more comfortable seeing .html than .php, so I've recently switched over.

I've not been able to figure out how to get a external javascript file to load from below root. When everything was Web-visible, I had stored it in the same folder as the php scripts. But when I moved it all below root, it doesn't seem to be found.

It makes no difference whether I write the path out or use php and the $hiddenFolder variable to write in the path.

Before I shifted the data to below root, the line was:

<script type="text/javascript" src="/scriptFolder/scriptFile.js"></script>

That works (but it's above root or Web-visible).

In all cases, the path looks fine in the page source.

I put a alert("hello world\n"); at the top of the js file, but that didn't pop up, so I'm guessing that the file simply isn't found.

[Interestingly, it appears that if the external javascript file can't be found, none of the <.noscript> text shows, either.]

Any ideas on how to handle an external javascript file stored below root? Maybe it's not possible?

isitreal

6:03 pm on Apr 8, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Re: visitors seeing php. Yes, that's why I give them what they are used to, htm or html, there is nothing unusual, which on the web is a very good thing.

Re loading a js file from below the root:

I've thought about this too, so I decided to make an experiment, which much to my surprise worked:

the html page is this:

<html>
<head>
<script type="text/javascript" src="js_loader.php"></script>
</head>
<body>
</body>
</html>

js_loader.php is this:


<?php
include('test/your_js_file.js');
?>

and the your_js_file.js is this:

alert('it worked');

I thought browsers might choke on the js file since it is being called with a php extension, but all browsers I tested this on happily returned 'it worked' alert boxes, including Netscape 4, 6, Opera 5, and all IE's

Thanks for asking that question, I had always assumed that this wouldn't work, now I have to see if I can use this for css files too.

A major downside I can think of is that you might lose the page load advantage of having the js file cached in the browser, the server will be returning the requested file to every page I believe using a method like this.

jamesa

7:28 pm on Apr 8, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



The javascript file needs to be publically visible. The reason you can't get a javascript file to load from below root is because that happens client-side, not server-side. It's the browser that fetches the page in the SRC attribute of the SCRIPT tag after it loads the HTML page - the exact same thing it does for images. By then the web server, and PHP, have already done their jobs and are out of the picture.

zollerwagner

7:38 pm on Apr 8, 2004 (gmt 0)

10+ Year Member



Wow, that really would be surprising. I've played with it for a half hour and can't get it to work. The Php file never loads for some reason. Maybe my host's server is set up differently.

As I laid down to sleep last night, it occurred to me that javascript, being client-side, can't call up anything that isn't Web-visible! Duh.

So your idea, having php provide it, makes sense.... I must be doing something wrong. But I think I'll just keep my javascript in a Web-visible folder and be done with it. Thanks for the idea.

zollerwagner

7:42 pm on Apr 8, 2004 (gmt 0)

10+ Year Member



Hello, Jamesa,

I was writing, testing out Isitreal's idea....and you beat me to it!

Exactly. It pays to take a break once in a while and consider the obvious, doesn't it?

Well, I think I'm done with this one. Thanks to you both!