php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #57792 dirname(__FILE__) doesn't work correctly in hard-linked files
Submitted: 2007-08-20 06:09 UTC Modified: 2008-01-29 21:44 UTC
From: sherwind at gmail dot com Assigned:
Status: Wont fix Package: APC (PECL)
PHP Version: 4.3.9 OS: Centos 4.5
Private report: No CVE-ID: None
View Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
If you reported this bug, you can edit this bug over here.
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: sherwind at gmail dot com
New email:
PHP Version: OS:

 

 [2007-08-20 06:09 UTC] sherwind at gmail dot com
Description:
------------
A file that require()s a config file located in dirname(__FILE__)
and outputs a constant is hard-linked in multiple sites hosted on the
same server. The constant for the site from which the file was requested the
first time gets cached and is returned in subsequent requests regardless
of the site.

It works fine if the file is *unhardlinked*. It also works if
dirname(__FILE__) is removed or just replaced with './'.

Reproduce code:
---------------
foo.example.com and bar.example.com have the same copies of test.php
and config.php.

# sha1sum /www/*/{test,config}.php
a0af22d58a7a7a5fd11547cd304cc08968c13d5c  /www/bar.example.com/test.php
a0af22d58a7a7a5fd11547cd304cc08968c13d5c  /www/foo.example.com/test.php
4494ec973dfed496e4b28f1ae6e4e2224d10a66c  /www/bar.example.com/config.php
4494ec973dfed496e4b28f1ae6e4e2224d10a66c  /www/foo.example.com/config.php

but test.php is hard-linked

# ls -il /www/*/{test,config}.php | awk '{print $1, $10}' | sort -rn
5640819 /www/foo.example.com/test.php
5640819 /www/bar.example.com/test.php
4792040 /www/bar.example.com/config.php
4792039 /www/foo.example.com/config.php

# cat /www/foo.example.com/test.php
<?php
require(dirname(__FILE__) . '/config.php');
echo ABSPATH;
?>

# cat /www/foo.example.com/config.php
<?php
define('ABSPATH', dirname(__FILE__).'/');
?>

Expected result:
----------------
"echo ABSPATH;" should return the ABSPATH for foo if foo.example.com is requested and the ABSPATH for bar if bar.example.com is requested.

Actual result:
--------------
# service httpd restart
Stopping httpd:                                            [  OK  ]
Starting httpd:                                            [  OK  ]

# curl -H 'Host: foo.example.com' http://127.0.0.1/test.php
/www/foo.example.com/

# curl -H 'Host: bar.example.com' http://127.0.0.1/test.php
/www/foo.example.com/

# service httpd restart
Stopping httpd:                                            [  OK  ]
Starting httpd:                                            [  OK  ]

# curl -H 'Host: bar.example.com' http://127.0.0.1/test.php
/www/bar.example.com/

# curl -H 'Host: foo.example.com' http://127.0.0.1/test.php
/www/bar.example.com/

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2007-11-25 22:15 UTC] shire@php.net
I believe this is caused because __FILE__ is a magic constant (http://us3.php.net/manual/en/language.constants.predefined.php).

These are defined at compile-time so the values are determined when you first request the file and it is cached.  Because this happens within the PHP compiler and not APC there's no easy solution for an APC fix here.  

You can probably work around this by retrieving your filename via some other functionality that gets executed on every request rather than evaluated at compilation.
 [2011-01-03 12:51 UTC] whfwoefh at wasteland dot rfc822 dot org
The XCache guys solved the problem:
See here:
http://xcache.lighttpd.net/ticket/117
and
http://xcache.lighttpd.net/wiki/AutoHardLinking

... so it's feasible!
Would be nice, if apc would be fixed too.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Dec 21 14:01:32 2024 UTC