By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,986 Members | 1,905 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,986 IT Pros & Developers. It's quick & easy.

Includes in libraries

P: n/a
A fairly simple question:

I have a library A which depends on library B and C.

Currently I have:

<?php
include("A.inc.php");
include("B.inc.php");
include("C.inc.php");
?>

....in my HTML.

This needs changing to:

<?php
include("../A.inc.php");
include("../B.inc.php");
include("../C.inc.php");
?>

....if I call it from deeper in the directory tree.

I don't want lots of includes in my HTML. I want to write:

<?php
include("A.inc.php");
?>

....and to have the other includes in the "A.inc.php" file.

However if I put:

include("B.inc.php");
include("C.inc.php");

....in the library, it doesn't fild the files when included using:

<?php
include("../A.inc.php");
?>

....in an HTML file some distance from the root.

I don't want to wire absolute paths in.

I *could* pass the "../" in as a method parameter - but that
seems like a total mess.

What is the best way to resolve this issue?
--
__________
|im |yler http://timtyler.org/ ti*@tt1lock.org Remove lock to reply.
Jul 17 '05 #1
Share this Question
Share on Google+
13 Replies


P: n/a
Tim Tyler wrote:
A fairly simple question:

I have a library A which depends on library B and C.

Currently I have:

<?php
include("A.inc.php");
include("B.inc.php");
include("C.inc.php");
?>

...in my HTML.

This needs changing to:

<?php
include("../A.inc.php");
include("../B.inc.php");
include("../C.inc.php");
?>

...if I call it from deeper in the directory tree.

I don't want lots of includes in my HTML. I want to write:

<?php
include("A.inc.php");
?>

...and to have the other includes in the "A.inc.php" file.

However if I put:

include("B.inc.php");
include("C.inc.php");

...in the library, it doesn't fild the files when included using:

<?php
include("../A.inc.php");
?>

...in an HTML file some distance from the root.

I don't want to wire absolute paths in.

I *could* pass the "../" in as a method parameter - but that
seems like a total mess.

What is the best way to resolve this issue?


Best idea is to put all your libraries in a single directory and add it
to include_path in php.ini.

Failing that you could look at the constant _FILE_ which, in A.inc will
point to the full path of A.inc (I think).

Jul 17 '05 #2

P: n/a
Tim Tyler <ti*@tt1lock.org> wrote or quoted:

[snip]
However if I put:

include("B.inc.php");
include("C.inc.php");

...in the library, it doesn't fi[n]d the files when included using:

<?php
include("../A.inc.php");
?>

...in an HTML file some distance from the root.

I don't want to wire absolute paths in.

I *could* pass the "../" in as a method parameter - but that
seems like a total mess.

What is the best way to resolve this issue?


Prepending $DOCUMENT_ROOT seems like a possible resolution.

It's not an ideal solution - since it too hinders portability,
by wiring in an path with an absoulte element.

i.e. if I ever want to move the library files relative to the
webserver's document root, then they would need rewriting.
--
__________
|im |yler http://timtyler.org/ ti*@tt1lock.org Remove lock to reply.
Jul 17 '05 #3

P: n/a
Kevin Thorpe <ke***@pricetrak.com> wrote or quoted:
Best idea is to put all your libraries in a single directory and add it
to include_path in php.ini.
Nooooooooooooooooooooooooooo! ;-)
Failing that you could look at the constant _FILE_ which, in A.inc will
point to the full path of A.inc (I think).


If so, that sounds like it will sort out the problem.

There's still the expense of writing a routine to strip off the leaf -
and including the body of this function in every library file that wants
to include other library files - of course.

However this is likely to be low maintenance code - and I don't mind
duplicating it all over the place - if that's /really/ what it takes.
--
__________
|im |yler http://timtyler.org/ ti*@tt1lock.org Remove lock to reply.
Jul 17 '05 #4

P: n/a
Tim Tyler <ti*@tt1lock.org> wrote or quoted:
Kevin Thorpe <ke***@pricetrak.com> wrote or quoted:

Failing that you could look at the constant _FILE_ which, in A.inc will
point to the full path of A.inc (I think).


If so, that sounds like it will sort out the problem.


Hah!

``If you use a relative path for include or include_one, the path is
relative to the running script, ie. the script that started all the
includes. Thereís no easy way to include files relative to the current
file. This is a real hassle if youíve got a library file that links to a
whole lot of other files. You can use absolute paths (with
$DOCUMENT_ROOT) but this is (obviously) less flexible.

Iíve finally figured out a solution, using _FILE_, realpath, and basedir:

include_once(realpath(dirname(__FILE__) . "../relative/path/to/file"))''

- http://www.ineffable.co.nz/archives/cat_php.html

So I reckon something like:

function include_once_relative($path) {
include_once(realpath(dirname(__FILE__)."../".$path));
}

....should patch things up - until the PHP designers fix up the problem.
--
__________
|im |yler http://timtyler.org/ ti*@tt1lock.org Remove lock to reply.
Jul 17 '05 #5

P: n/a
Tim Tyler wrote:
A fairly simple question:


Well, another way (than the other answers) are to add another include
directory by ini_set() and the "include_path" option.

Regards,
Johan

Jul 17 '05 #6

P: n/a
I, Tim Tyler <ti*@tt1lock.org> wrote or quoted:
``If you use a relative path for include or include_one, the path is
relative to the running script, ie. the script that started all the
includes. Thereís no easy way to include files relative to the current
file. This is a real hassle if youíve got a library file that links to a
whole lot of other files. You can use absolute paths (with
$DOCUMENT_ROOT) but this is (obviously) less flexible.

Iíve finally figured out a solution, using _FILE_, realpath, and basedir:

include_once(realpath(dirname(__FILE__) . "../relative/path/to/file"))''

- http://www.ineffable.co.nz/archives/cat_php.html

So I reckon something like:

function include_once_relative($path) {
include_once(realpath(dirname(__FILE__)."../".$path));
}

...should patch things up - until the PHP designers fix up the problem.


That fails miserably on Windows running off a local webserver.

include_once("C:\Documents\HTML\~TimTyler\php\test \i.inc.php");

....isn't valid - you see.

As it stands, this solution is not acceptable - since it doesn't work.
--
__________
|im |yler http://timtyler.org/ ti*@tt1lock.org Remove lock to reply.
Jul 17 '05 #7

P: n/a
Tim Tyler <ti*@tt1lock.org> wrote or quoted:
I, Tim Tyler <ti*@tt1lock.org> wrote or quoted:

``If you use a relative path for include or include_one, the path is
relative to the running script, ie. the script that started all the
includes. Thereís no easy way to include files relative to the current
file. This is a real hassle if youíve got a library file that links to a
whole lot of other files. You can use absolute paths (with
$DOCUMENT_ROOT) but this is (obviously) less flexible.

Iíve finally figured out a solution, using _FILE_, realpath, and basedir:

include_once(realpath(dirname(__FILE__) . "../relative/path/to/file"))''

- http://www.ineffable.co.nz/archives/cat_php.html

So I reckon something like:

function include_once_relative($path) {
include_once(realpath(dirname(__FILE__)."../".$path));
}

...should patch things up - until the PHP designers fix up the problem.


That fails miserably on Windows running off a local webserver.

include_once("C:\Documents\HTML\~TimTyler\php\test \i.inc.php");

...isn't valid - you see.

As it stands, this solution is not acceptable - since it doesn't work.


Here is something that /does/ appear to work - at least in *my*
development and deployment environments, on *my* test data:

// test code...
include_once_relative("test.inc.php");

function include_once_relative($path) {
$from = realpath(dirname($_SERVER["SCRIPT_FILENAME"]));
$to = realpath(dirname(__FILE__)."/".$path);

include_once(relative_path($to,$from));
}

function relative_path ($targetfile, $basedir = '.') {
$basedir = realpath ($basedir);
$targetfile = realpath ($targetfile);

// on windows, check that both paths are on the same drive
if (substr ($basedir, 0, 1) != substr ($targetfile, 0, 1)) {
return false;
}

// split each path into its directories
$base_parts = split ('\/', str_replace ('\\', '/', $basedir));
$target_parts = split ('\/', str_replace ('\\', '/', $targetfile));

// ensure that there are no empty elements at the end (c:\ would cause it)
for ($i = count($base_parts) - 1; $i >= 0; $i--) {
if ($base_parts[$i] == '') {
unset ($base_parts[$i]);
} else {
break;
}
}
for ($i = count($target_parts) - 1; $i >= 0; $i--) {
if ($target_parts[$i] == '') {
unset ($target_parts[$i]);
} else {
break;
}
}

// get rid of the common directories at the beginning of the paths
$common_count = 0;
for ($i = 0; $i < count($base_parts); $i++) {
if ($target_parts[$i] == $base_parts[$i]) {
$common_count++;
} else {
break;
}
}
for ($i = 0; $i < $common_count; $i++) {
unset ($base_parts[$i]);
unset ($target_parts[$i]);
}

// build the resulting string
$cnt = count($base_parts) - 1;
if ($cnt < 1) {
$cnt = 0;
}

return str_repeat ('../', $cnt).implode('/', $target_parts);
}

Of course, this is now A Dreadful Hack :-|
--
__________
|im |yler http://timtyler.org/ ti*@tt1lock.org Remove lock to reply.
Jul 17 '05 #8

P: n/a
On Tue, 02 Dec 2003 14:58:07 +0000, Tim Tyler wrote:
A fairly simple question:

I have a library A which depends on library B and C.

Currently I have:

<?php
include("A.inc.php");
include("B.inc.php");
include("C.inc.php");
?>

...in my HTML.

This needs changing to:

<?php
include("../A.inc.php");
include("../B.inc.php");
include("../C.inc.php");
?>

...if I call it from deeper in the directory tree.

I don't want lots of includes in my HTML. I want to write:

<?php
include("A.inc.php");
?>

...and to have the other includes in the "A.inc.php" file.

However if I put:

include("B.inc.php");
include("C.inc.php");

...in the library, it doesn't fild the files when included using:

<?php
include("../A.inc.php");
?>

...in an HTML file some distance from the root.

I don't want to wire absolute paths in.

I *could* pass the "../" in as a method parameter - but that seems like a
total mess.

What is the best way to resolve this issue?

Tim..

I normally create a 'registry.php' file. This holds the instructions for
my includes. It might look something like:
<?php
/* Script: includes/registry.php */

$global_libs = array(
'Mysql',
'Sessions',
'smarty/Smarty'
);
foreach ($global_libs as $g_lib) {
require_once("$g_lib.class.php");
}

$local_includes = array(
'functions',
'constants'
);
foreach ($local_includes as $l_inc) {
require_once(SITE_ROOT . "/includes/$l_inc.inc.php");
}
?>
Then a script to call this would look like:

<?php
/* Script: index.php */
define('SITE_ROOT', dirname(__FILE__));
require_once(SITE_ROOT . '/includes/registry.php');

[ ... rest of script ... ]
?>
Or if we're in a sub directory:

<?php
/* Script: subdir/foo.php */
define('SITE_ROOT', dirname(__FILE__) . '/..');
require_once(SITE_ROOT . '/includes/registry.php');

[ ... rest of script ... ]
?>
As you an see, it doesn't matter what dir you in or how deep into a tree
you are, as long as you define the SITE_ROOT correctly (with enough
/../../.. etc) you'll always have the right place to read for the
registry.php script.

I use arrays to store the stuff in the registry script as it makes life
easier if you want to add / remove / whatever any of the files.

My £0.02 worth anyway =)

Regards,

Ian

--
Ian.H [Design & Development]
digiServ Network - Web solutions
www.digiserv.net | irc.digiserv.net | forum.digiserv.net
Programming, Web design, development & hosting.

Jul 17 '05 #9

P: n/a
Johan Holst Nielsen <jo***@weknowthewayout.com> wrote or quoted:
Tim Tyler wrote:

A fairly simple question:


Well, another way (than the other answers) are to add another include
directory by ini_set() and the "include_path" option.


Essentially this idea has been suggested twice.

Doesn't doing something like this cause everything to become slow
if many modules do it, and there's a big string of directories to
scan?

What is the "scope" of the "include_path"?

Doesn't using it set you up for probems with name clashes with any
other users' scripts that do the same?
--
__________
|im |yler http://timtyler.org/ ti*@tt1lock.org Remove lock to reply.
Jul 17 '05 #10

P: n/a
Tim Tyler wrote:
Kevin Thorpe <ke***@pricetrak.com> wrote or quoted:
Best idea is to put all your libraries in a single directory and add it
to include_path in php.ini.


Nooooooooooooooooooooooooooo! ;-)


why not?

Jul 17 '05 #11

P: n/a
Adi Schwarz <ad**********************@gmx.at> wrote or quoted:
Tim Tyler wrote:
Kevin Thorpe <ke***@pricetrak.com> wrote or quoted:
Best idea is to put all your libraries in a single directory and add it
to include_path in php.ini.


Nooooooooooooooooooooooooooo! ;-)


why not?


I expressed some of my qualms about this sort of thing in my reply to
Johan Holst Nielsen's suggestion.

Also it contains the sentence fragment:

"Best idea is to put all your libraries in a single directory".

I regard that as a dreadful idea - since I want to use directories
for encapsuating/associating files within each library - e.g. like
a Java package usually does - and I want my libraries associated
with the domains where they are used - to limit the scope of damage
if I want to change an API.
--
__________
|im |yler http://timtyler.org/ ti*@tt1lock.org Remove lock to reply.
Jul 17 '05 #12

P: n/a
Regarding this well-known quote, often attributed to Tim Tyler's famous
"Tue, 2 Dec 2003 14:58:07 GMT" speech:
A fairly simple question:

I have a library A which depends on library B and C.

Currently I have:

<?php
include("A.inc.php");
include("B.inc.php");
include("C.inc.php");
?>

...in my HTML.

This needs changing to:

<?php
include("../A.inc.php");
include("../B.inc.php");
include("../C.inc.php");
?>

...if I call it from deeper in the directory tree.

I don't want lots of includes in my HTML. I want to write:

<?php
include("A.inc.php");
?>

...and to have the other includes in the "A.inc.php" file.

However if I put:

include("B.inc.php");
include("C.inc.php");

...in the library, it doesn't fild the files when included using:

<?php
include("../A.inc.php");
?>

...in an HTML file some distance from the root.

I don't want to wire absolute paths in.

I *could* pass the "../" in as a method parameter - but that
seems like a total mess.

What is the best way to resolve this issue?


You could just drop a "definitions" script within your root path, and
include that from the included files:

<includes.inc.php> -----------------------------------------------

$_ROOT_INC_PATH_ = "/home2/bobdrilo/public_html/php-includes";

$_MYSQL_LIB_PATH_ = "$_ROOT_INC_PATH_/mysql/mysql-lib.php";
$_GRAPHICS_LIB_PATH_ = "$_ROOT_INC_PATH_/graphicslib/gfxlib.php";
$_TABLEGEN_LIB_PATH_ = "$_ROOT_INC_PATH_/tables/tables.php";

....

<includes.inc.php> -----------------------------------------------

then, call your includes with the variables:

<dostuff.php> ----------------------------------------------------
include("includes.inc.php"); // this is in the root includes path
include($_GRAPHICS_LIB_PATH_);
include($_MYSQL_LIB_PATH);

....
<dostuff.php> ----------------------------------------------------

--
-- Rudy Fleminger
-- sp@mmers.and.evil.ones.will.bow-down-to.us
(put "Hey!" in the Subject line for priority processing!)
-- http://www.pixelsaredead.com
Jul 17 '05 #13

P: n/a
Tim Tyler wrote:
Johan Holst Nielsen <jo***@weknowthewayout.com> wrote or quoted:
Tim Tyler wrote:
A fairly simple question:


Well, another way (than the other answers) are to add another include
directory by ini_set() and the "include_path" option.

Doesn't doing something like this cause everything to become slow
if many modules do it, and there's a big string of directories to
scan?

I would not say that.

Let's say you have all includes (with subdirectories) in /bla/includes/
- this path is in you include_path.

If your script is in
/bla/scripts/dir/blubb.php
and wants to include
/bla/includes/modules/blubb.inc.php you just have to
include("modules/blubb.inc.php");

If you want to move your script directory - no problem.
If you want to move your include base directory - just adjust the
inlude_path

Doesn't using it set you up for probems with name clashes with any
other users' scripts that do the same?


You can set the include_path for each user with an .htaccess (can't
you?) or in the script itself.

I really see advantages only.

Greets,
-adi

Jul 17 '05 #14

This discussion thread is closed

Replies have been disabled for this discussion.