0

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?

Rob
  • 7,980
  • 30
  • 75
  • 115

6 Answers6

5

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.

Your Common Sense
  • 156,878
  • 40
  • 214
  • 345
Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
  • +1. but I'd recommend includes relative to `dirname(__FILE__)` instead. – Michael Krelin - hacker Apr 26 '10 at 14:56
  • @Michael absolute path always preferred over relative. Because it can be set regardless of current directory. – Your Common Sense Apr 26 '10 at 15:07
  • @Col, I meant as in `include dirname(__FILE__)."/file.php";`, so it is absolute path, you just specify it relatively. – Michael Krelin - hacker Apr 26 '10 at 15:13
  • @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 – Your Common Sense Apr 26 '10 at 15:18
  • 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 Apr 26 '10 at 15:23
  • So how would this calculate the complete filepath, if the file is in a different directory? – Rob Apr 26 '10 at 15:23
  • 1
    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 Apr 26 '10 at 15:26
  • 1
    +-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 Apr 26 '10 at 15:29
  • Col, Pekka, you (we) make some valid points here, but are they relevant to the question in question? ;-) – Michael Krelin - hacker Apr 26 '10 at 15:31
  • @Michael I have quoted the OP's question. It is clear and unambiguous: how to include one file in different places. – Your Common Sense Apr 26 '10 at 15:39
  • Sorry Michael, but Col. Shrapnel is correct in what I'm looking to accomplish – Rob Apr 26 '10 at 15:51
  • 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 Apr 26 '10 at 16:50
  • 1
    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* – Kzqai Apr 26 '10 at 18:16
1

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.

Kzqai
  • 22,588
  • 25
  • 105
  • 137
  • Including the local file causes an http request? – thetaiko Apr 26 '10 at 14:58
  • 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 Apr 26 '10 at 15:05
  • I can't get relation between _once and code reuse. What if I use include with function library? – Your Common Sense Apr 26 '10 at 15:13
  • 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. – Kzqai Apr 26 '10 at 18:09
1

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 -Malimovka
  • 52,579
  • 61
  • 190
  • 278
1

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
  • 6,756
  • 9
  • 44
  • 63
  • so it would be for example: include("BASE_DIR/var/www/html/somedirectory/file.php"); or did I misunderstand? – Rob Apr 26 '10 at 15:07
  • but it has to be defined in every running script – Your Common Sense Apr 26 '10 at 15:10
  • Forget it @Rob, this answer helps nothing. this constant has to be defined somehow. It can't help you include from various places – Your Common Sense Apr 26 '10 at 15:11
  • @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 Apr 26 '10 at 15:26
  • @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 – Your Common Sense Apr 26 '10 at 15:34
  • 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 Apr 26 '10 at 17:17
1

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
  • 138,757
  • 24
  • 193
  • 173
0

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
  • 92,914
  • 28
  • 189
  • 235