views:

79

answers:

6

Just something I wonder about when including files:

Say I want to include a file, or link to it. Should I just for example:

include("../localfile.php");

or should I instead use

include("http://sameserver.com/but/adirect/linkto/localfile.php");

Is one better than the other? Or more secure? Or is it just personal preference?

Clearly it would be a necessity if you had a file that you would include into files in multiple directories, and THAT file includes a different file, or is there some other way of doing that?

+5  A: 

Reading a file is much faster than making an HTTP request and getting the response. Never include(a_uri) if you can help it.

Use $_SERVER['DOCUMENT_ROOT'] if you want to calculate a complete file path for your include.

David Dorward
+1. but I'd recommend includes relative to `dirname(__FILE__)` instead.
Michael Krelin - hacker
@Michael absolute path always preferred over relative. Because it can be set regardless of current directory.
Col. Shrapnel
@Col, I meant as in `include dirname(__FILE__)."/file.php";`, so it is absolute path, you just specify it relatively.
Michael Krelin - hacker
@Michael no you said `relative`, and it IS relative. Relative from the current file. But the OP wants absolute one, to include into files in multiple directories. $_SERVER['DOCUMENT_ROOT'] is the best
Col. Shrapnel
Col, How do you know OP wants the absolute path? And while my original wording was somewhat unclear, your original concern doesn't apply. The rest depends on many circumstances, OP's real intention and taste too.
Michael Krelin - hacker
So how would this calculate the complete filepath, if the file is in a different directory?
Rob
Rob, that implies you know where the file you include is *relative* to the file that includes it. Suppose, the file `..../a/a.php` includes `..../b/b.php`, then it will be like `include dirname(__FILE__).'/../b/b.php`;` but if you realy want it relative to document root, then use the original proposal.
Michael Krelin - hacker
+-0 `DOCUMENT_ROOT` is fine if your product is always going to run in the root directory. It is not if it needs to be installable in subdirectories as well. Also, `DOCUMENT_ROOT` won't be available when portions of the app are called through CLI. I think a bootstrap defining the site root is (unfortunately) often unavoidable.
Pekka
Col, Pekka, you (we) make some valid points here, but are they relevant to the question in question? ;-)
Michael Krelin - hacker
@Michael I have quoted the OP's question. It is clear and unambiguous: how to include one file in different places.
Col. Shrapnel
Sorry Michael, but Col. Shrapnel is correct in what I'm looking to accomplish
Rob
Then you got your answers, Rob ;-) But bear in mind that if you have to move your whole application from `/app1` to `/app2` you're going to suffer, unless you follow Pekka's advice.
Michael Krelin - hacker
From the manual: `$_SERVER is an array containing information such as headers, paths, and script locations. The entries in this array are created by the web server. There is no guarantee that every web server will provide any of these; servers may omit some, or provide others not listed here.` http://php.net/manual/en/reserved.variables.server.php So yeah, you're pretty explicitly not supposed to rely on that superglobal being defined. *shrugs*
Tchalvak
+1  A: 

Definitely include the local file, because the php script doesn't really know or care that you're including a script on your local server, so the url path causes an http request, and network latency from http requests is pretty much the bottleneck for rendering any html page in general, the fewer of them you have, the better off you're going to be.

Personally, I try to avoid using include and require in general, in favor of require_once, because using require_once means that you are writing your code reusably instead of writing code that executes immediately when you include it. Pull in class definitions, pull in function libraries, but try to avoid code that executes immediately when you include it, because that will make it harder to reuse.

Tchalvak
Including the local file causes an http request?
thetaiko
Heh, right, corrected th' bad grammar.
Tchalvak
The `_once` functions add significant overhead to includes because the interpreter must see if it has been included yet. If you're using an autoloading system -- which you should be (it's in any modern framework) -- you shouldn't have to use the `_once` functions.
ryeguy
I can't get relation between _once and code reuse. What if I use include with function library?
Col. Shrapnel
Let's see if I can make a quick example: Script Defs.php has some reusable code. Script Alpha.php and Beta.php both use the functions or classes defined in Script Defs.php. Script Delta.php reuses code from both Alpha and Beta. If Alpha or Beta use include or require instead of `require_once`, then you're just going to get function or class redefinition errors. So I usually find include and require to be a "code smell" (much as I hate that term), a symptom of a block of code that isn't reusable.
Tchalvak
A: 

Always include locally, cause if you include remote someone can create a different file and do nasty things. And the other problem you can't really test this with remote includes. As far as i know you should use require_once instead...

khmarbaise
+1  A: 

As said before, definitely include a local file and not do an HTTP request (which takes more time, is not cached and the contents are technically viewable to all the world, if he knows where to look for it).
One more small detail, if you use full paths to your included files, it will even be faster then relative paths, especially if you use some kind Byte Code Cache.

Itay Moav
Full paths aren't really worth the maintenance overhead, in my opinion.
Tchalvak
@Tchalvak what you have instead?
Col. Shrapnel
Why the downvote?
Pekka
Full paths aren't worth the maintenance? Do you really declare a path for every file you call instead of declaring a path in a class var or a constant? Do you also put your table names in you SQL instead of declaring those in variables as well?
Elizabeth Buckwalter
+1  A: 

If your question is about keeping it so you don't have to change a billion paths when you move from staging to production, go with this little tidbit I learned:

 define('BASE_DIR',  '/path/to/root/');

Then use BASE_DIR in all of your path references. When it's time to move your site, just change that definition to the new path (which should just be / at that point).

dclowd9901
so it would be for example: include("BASE_DIR/var/www/html/somedirectory/file.php"); or did I misunderstand?
Rob
but it has to be defined in every running script
Col. Shrapnel
Forget it @Rob, this answer helps nothing. this constant has to be defined somehow. It can't help you include from various places
Col. Shrapnel
@Col `DOCUMENT_ROOT` is not a reliable indicator either if your site or application is installed in a subdirectory. This way is the only way known to me that works reliably, even though yes, you have to include a bootstrap file every time. Therefore, +1
Pekka
@Pekka but it isn't a "method" at all. it is just manual setting, with some syntax sugar, but still manual, with all it's disadvantages. Using Front controller is another option, but in general, DOCUMENT_ROOT most be first to try
Col. Shrapnel
False. I put this definition in my `header.php`. It is automatically called with every page. This isn't rocket science, guys. The idea is to be able to quickly change the basis of your root directory. Implement it however you like. All I know is calling to $_SERVER is very hit-or-miss in my experience.
dclowd9901
+1  A: 

In addition to what other people say, these invocations will have different results, since the remove invocation will execute php output, not the file contents. Unless you stop php from processing the file, in which case you're exposing your code to the world which is also not necessarily what you actually want to.

Michael Krelin - hacker