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

Bad php behaviour with related paths

P: n/a

Hello all

I'm trying to include some files in an included file. Think of some scripts
like this

/index.php
/scripts/logging.php
/scripts/config.php
/scripts/db_access.php

index.php includes 'scripts/logging.php' and logging.php includes
'config.php' ºi 'db_access.php'.

My problem is that from within logging.php the php will try to include the
file '/config.php' and not '/scripts/config.php' because logging.php is
included in '/index.php' in the first place.

I would use absolute paths in the included file names, built with
$_SERVER['DOCUMENT_ROOT'], but I don't really know where my pages are on
the web server. I just know they are somewhere under DocumentRoot.

How can I write pages that can translate local paths to virtual paths and
that can be moved from one place to another in the virtual directory
hierarhy and still function corectly ?

How can I write pages that know about each other's URI's and that do not
care where they are placed on the webserver with respect to DocumentRoot ?
--
Thank you
Timothy Madden
Romania
------------------------------------
And I don't wanna miss a thing
Jul 17 '05 #1
Share this Question
Share on Google+
7 Replies


P: n/a
"Timothy Madden" wrote:
Hello all

I’m trying to include some files in an included file. Think of
some scripts
like this

/index.php
/scripts/logging.php
/scripts/config.php
/scripts/db_access.php

index.php includes ’scripts/logging.php’ and logging.php
includes
’config.php’ ºi ’db_access.php’.

My problem is that from within logging.php the php will try to include the
file ’/config.php’ and not
’/scripts/config.php’ because logging.php is
included in ’/index.php’ in the first place.

I would use absolute paths in the included file names, built with
$_SERVER[’DOCUMENT_ROOT’], but I don’t really know
where my pages are on
the web server. I just know they are somewhere under DocumentRoot.

How can I write pages that can translate local paths to virtual paths and
that can be moved from one place to another in the virtual directory hierarhy and still function corectly ?

How can I write pages that know about each other’s URI’s
and that do not
care where they are placed on the webserver with respect to
DocumentRoot ?


Timothy, you don’t have to worry about where the files are on the
server. All you have to worry about is correctly setting up the paths
relative to the TOP calling script (in your case, where index.php
resides).

If you do it this way it will work:
in index.php ... include("./scripts/logging.php")
in logging.php ... include("./scripts/config.php")

You cannot say in logging.php ... include("config.php") since php
will look at the root to resolve this.

Hope this helps. This is one of the IMHO "weaknesses" of php, and
your situation comes up every day on usenet, so you are not alone.

--
http://www.dbForumz.com/ This article was posted by author's request
Articles individually checked for conformance to usenet standards
Topic URL: http://www.dbForumz.com/PHP-Bad-beha...ict136912.html
Visit Topic URL to contact author (reg. req'd). Report abuse: http://www.dbForumz.com/eform.php?p=457260
Jul 17 '05 #2

P: n/a
Why don't you put 'scripts' in the include_path in your php.ini file? That
is what it is there for.

--
Tony Marston

http://www.tonymarston.net
"Timothy Madden" <ba****@rmv.spam.home.ro> wrote in message
news:uz****************************@40tude.net...

Hello all

I'm trying to include some files in an included file. Think of some scripts like this

/index.php
/scripts/logging.php
/scripts/config.php
/scripts/db_access.php

index.php includes 'scripts/logging.php' and logging.php includes
'config.php' ºi 'db_access.php'.

My problem is that from within logging.php the php will try to include the
file '/config.php' and not '/scripts/config.php' because logging.php is
included in '/index.php' in the first place.

I would use absolute paths in the included file names, built with
$_SERVER['DOCUMENT_ROOT'], but I don't really know where my pages are on
the web server. I just know they are somewhere under DocumentRoot.

How can I write pages that can translate local paths to virtual paths and
that can be moved from one place to another in the virtual directory
hierarhy and still function corectly ?

How can I write pages that know about each other's URI's and that do not
care where they are placed on the webserver with respect to DocumentRoot ?
--
Thank you
Timothy Madden
Romania
------------------------------------
And I don't wanna miss a thing

Jul 17 '05 #3

P: n/a
Timothy Madden <ba****@rmv.spam.home.ro> wrote or quoted:
I'm trying to include some files in an included file. Think of some scripts
like this

/index.php
/scripts/logging.php
/scripts/config.php
/scripts/db_access.php

index.php includes 'scripts/logging.php' and logging.php includes
'config.php' ?i 'db_access.php'.

My problem is that from within logging.php the php will try to include the
file '/config.php' and not '/scripts/config.php' because logging.php is
included in '/index.php' in the first place.

I would use absolute paths in the included file names, built with
$_SERVER['DOCUMENT_ROOT'], but I don't really know where my pages are on
the web server. I just know they are somewhere under DocumentRoot.

How can I write pages that can translate local paths to virtual paths and
that can be moved from one place to another in the virtual directory
hierarhy and still function corectly ?

How can I write pages that know about each other's URI's and that do not
care where they are placed on the webserver with respect to DocumentRoot ?


You /could/ use this code:

<?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);
}

?>

Then calling "include_once_relative" with relative paths would include
paths relative to the library code, not relative to the document.
--
__________
|im |yler http://timtyler.org/ ti*@tt1lock.org Remove lock to reply.
Jul 17 '05 #4

P: n/a
steve <Us************@dbforumz.com> wrote or quoted:
"Timothy Madden" wrote: Timothy, you don?t have to worry about where the files are on the
server. All you have to worry about is correctly setting up the paths
relative to the TOP calling script (in your case, where index.php
resides).
That is not a feasible solution for library code which needs
to include other library code.

It results in the caller being required to manually include all the
needed library files, instead of just one of them (which includes all
the rest).
You cannot say in logging.php ... include("config.php") since php
will look at the root to resolve this.

Hope this helps. This is one of the IMHO "weaknesses" of php, and
your situation comes up every day on usenet, so you are not alone.


It is indeed a disasterous design decision by the PHP authors :-(

There are work-arounds - but they are not neat - and PHP seems to badly
need an "include_relative" function built into its core.
--
__________
|im |yler http://timtyler.org/ ti*@tt1lock.org Remove lock to reply.
Jul 17 '05 #5

P: n/a
Tony Marston <to**@nospam.demon.co.uk> wrote or quoted:
Why don't you put 'scripts' in the include_path in your php.ini file? That
is what it is there for.


Modularily, encapsulation, not messing up the global namespace,
not requing users of your code to have access to the php.ini file -
there are *lots* of good reasons for not going down that path.
--
__________
|im |yler http://timtyler.org/ ti*@tt1lock.org Remove lock to reply.
Jul 17 '05 #6

P: n/a
If you don't have access to the php.ini file there are several ways to
change the settings:
(a) By using a .htaccess file (assuming you are using Apache)
(b) By using ini_set().

If I were wring software that needed to be initiated by include(), and this
software used include() on files in subdirectories, then I would write it so
that it worked.

If enough people requested an include_relative() function then I'm sure the
authors of PHP would add it in. But it seems that only a small number
*think* that it's necessary while the rest of us write code that doesn't
need it.

--
Tony Marston

http://www.tonymarston.net
"Tim Tyler" <ti*@tt1lock.org> wrote in message news:I2********@bath.ac.uk...
Tony Marston <to**@nospam.demon.co.uk> wrote or quoted:
Why don't you put 'scripts' in the include_path in your php.ini file?
That
is what it is there for.


Modularily, encapsulation, not messing up the global namespace,
not requing users of your code to have access to the php.ini file -
there are *lots* of good reasons for not going down that path.
--
__________
|im |yler http://timtyler.org/ ti*@tt1lock.org Remove lock to reply.

Jul 17 '05 #7

P: n/a

"steve" <Us************@dbForumz.com> wrote in message
news:41**********@news.athenanews.com...
"Timothy Madden" wrote:
> Hello all
>
> I'm trying to include some files in an included file. Think of
> some scripts
> like this
>
> /index.php
> /scripts/logging.php
> /scripts/config.php
> /scripts/db_access.php
>
> index.php includes 'scripts/logging.php' and logging.php
> includes
> 'config.php' ºi 'db_access.php'.
>
> My problem is that from within logging.php the php will try to

include
> the
> file ’/config.php’ and not
> ’/scripts/config.php’ because logging.php is
> included in ’/index.php’ in the first place.
>
> I would use absolute paths in the included file names, built with
> $_SERVER[’DOCUMENT_ROOT’], but I don’t really know
> where my pages are on
> the web server. I just know they are somewhere under DocumentRoot.
>
> How can I write pages that can translate local paths to virtual

paths
> and
> that can be moved from one place to another in the virtual

directory
> hierarhy and still function corectly ?
>
> How can I write pages that know about each other’s URI’s
> and that do not
> care where they are placed on the webserver with respect to
> DocumentRoot ?
>
>


Timothy, you don't have to worry about where the files are on the
server. All you have to worry about is correctly setting up the paths
relative to the TOP calling script (in your case, where index.php
resides).

If you do it this way it will work:
in index.php ... include("./scripts/logging.php")
in logging.php ... include("./scripts/config.php")

You cannot say in logging.php ... include("config.php") since php
will look at the root to resolve this.

Hope this helps. This is one of the IMHO "weaknesses" of php, and
your situation comes up every day on usenet, so you are not alone.

After a few moths ...
Time has passed, PHP 5 appeared, docs got a little better and now the
answer camed:

There is a constant named __FILE__ that is the name of the current
(included) file. With it I can get the base directory and compose the path
to other included files.

And __FILE__ was there since PHP 4.0, this was just a problem of
the quality of documentation for PHP (which I find to be very good
otherwise)

Timothy Madden
Romania
---------------------------------------------
And I don't wanna miss a thing
(remove 'rmv.spam' from my mail address)
Jul 17 '05 #8

This discussion thread is closed

Replies have been disabled for this discussion.