note 8967 deleted from function.include by philip
| From: | philip@php.net | Date: | Fri, 02 Nov 2001 06:53:54 +0000 |
| Subject: | note 8967 deleted from function.include by philip | ||
| References: | 1 | Groups: | php.notes |
| Request: | Send a blank email to php-notes+get-20273@lists.php.net to get a copy of this message | ||
[Editor's note: Use include_once() or require_once() for a solution to multiple file inclusion,
also include w/ respect to the document root to avoid similar problems, or put the include dirs in
the include_path configuration file this will sidestep the relative path problems that can occur.]
I've been working on a project in PHP that keeps getting larger and larger, with my source tree
getting bigger and bigger.
I had been sidestepping the issue of include()ing a file from another file by being very careful as
to where dependencies were. For instance:
a.php
actions/b.php
conf/c.php
Having a.php include() conf/c.php is fine. However, if only b.php needs c.php, what you'd like
to do is have b.php include("../conf/c.php"). Now, the problem people run up against is
that if a.php include()s b.php, and b.php is set to include("../conf/c.php"), b.php
won't be able to find "../conf/c.php"! That's because php stay's in
a.php's directory.
As I said before, I dealt with this by sidestepping the issue. I was always calling
"b.php" from the a.php directory, so I include()d "conf/c.php" and things
worked.
It finally bit me in the butt last week. So, I broke down redid the include statements on my site.
Here's what I do now... any include()s are wrapped in chdir()s. To continue my example from
above (within a.php):
$old_a_php_dir = getcwd();
chdir("actions");
include("b.php");
chdir($old_a_php_dir);
Now, when b.php include()s c.php (that include is also wrapped in chdir()s), it can find c.php. The
truly nice part about all this is that there's no hard-wiring here, so when I move my site to
another box with a different $DOCUMENT_ROOT, it should all continue to work.
Warnings:
I used to use require() exclusively. However, since require() does it's thing very early on
(i.e., before any chdir()s can be executed), this trick will only work with include().
Also, I lied a little. I don't actually include("b.php"). I
include("../actions/b.php"). Since you are in "actions/", it's the same
thing, but I think it helps readability.
BIG HUGE AMAZING WARNING:
You have to be VERY careful to uniquely name your $old_dir variable from getcwd(). Think about
it... you're include()ing files left and right, all of which are using the same method. If all
your variables are name $old_dir, it gets overwritten with each include()! There are various clever
things one could do about this, but I prefer the simple approach show above. That is, use the
filename itself as part of the variablename. Prepend the directory name if you like to have lots of
files with the same name. Just be careful!
BTW - I also use define("__B_PHP__", 1) to deal with multiple inclusions, but there are
other posts here that explain the problem/solution very well, so it's not repeated here.
Giving back...
Wes Hertlein