php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #56596 value of __FILE__ is compiled into bytecode
Submitted: 2005-10-14 11:34 UTC Modified: 2010-12-03 08:37 UTC
From: r dot vanicek at seznam dot cz Assigned:
Status: Closed Package: bcompiler (PECL)
PHP Version: 4.4.0 OS: Linux
Private report: No CVE-ID: None
 [2005-10-14 11:34 UTC] r dot vanicek at seznam dot cz
Description:
------------
I am using PHP 4.4.0 with bcompiler 0.7.

The problem is that if the script uses __FILE__, it is bytecompiled and if the script is copied to another system and located in another directory, the value of __FILE__ is not the 'true' one (the run-time value) but the compile-time value.

Eg: require_once(dirname(__FILE__).'/cmn/module.php');

may not find the module.



Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2005-10-14 11:53 UTC] r dot vanicek at seznam dot cz
The easy test is like this:

let us have file test.php:
<?php echo __FILE__; ?>

then byte-compile it into test1.php,

and then run test.php and test1.php. They both produce the same output (ie. they both show the full path of test.php, the original file), while they should be different.
 [2005-10-17 03:06 UTC] r dot vanicek at seznam dot cz
Maybe it is not a bug, but a feature. But in this case it would be better to note this in the docs, so that users are not confused and update the applications if needed.

I gave it the second thought over the weekeend and it is right, that if someone wants to compile several source files into one byte-file or executable (like php-gtk app), and the application encounters an error, it is not possible to locate the position of the file and line of error in original sources. And preserving original __FILE__ and __LINE__ may help a lot. 

On the other hand, some apps (especially on the web) may rely on including some files relative to __FILE__ and these are broken for now.

Maybe there could be some compile-time switch to preserve the original __FILE__ or not.
 [2005-10-25 00:39 UTC] alan at akbkhome dot com
I suspect it's a bit tricky fixing this (from what I recall the bytecode generator inside zend may be converting these before bcompiler gets to see the bytecodes) 

It should be documented I guess (any volunteers ;)
 [2005-12-20 13:53 UTC] val@php.net
It's not a bug. Value of __FILE__ is expanded when parsing, so bytecode already has it as a string expression.

For example, the following scripts will have the same bytecode:
(/some/dir/test.php)
<?php echo __FILE__; ?>
(/some/dir/test.php)
<?php echo "/some/dir/test.php"; ?>
 [2010-04-04 20:05 UTC] mail at daniel-berlin dot de
Another method to reliably get the current file is:

call_user_func(array(new Exception(), "getFile"));

so you could write:

require dirname(__FILE__).'/foo.php';

as:

require dirname(call_user_func(array(new Exception(), "getFile"))) . "/foo.php";
 [2010-06-14 17:01 UTC] webadmin at aport dot ru
Thank you very much, daniel-berlin! This is a best method for 
get directory without translate it to static text in bytecode:

$dir = call_user_func(array(new Exception(), "getFile"));

Thank you again! :)
 [2010-08-13 21:41 UTC] alan at akbkhome dot com
It looks like Exception::getFile() is broken in 5.3 hence 
the workaround breaks.

This may be a issue with setting up stuff when bcompiler 
runs stuff.

It's advised generally not to depend on absolute paths, but 
to set up include_path correctly in the bootstrap code and 
use relative paths to include things.
 [2010-10-20 08:03 UTC] alan at akbkhome dot com
This is rather a messy patch - needs better testing of types 
etc.

But the basic idea is that __BCOMPILER_FILE__
gets replaced with the compiled filename when it get's 
rebuilt..


Can you test this with a few files and see if it breaks..

@@ -3668,6 +3681,20 @@
 			break;
 	}
 #endif
+
+    if (zo->opcode == ZEND_FETCH_CONSTANT && 
+		((&zo->op2)->op_type == IS_CONST) &&
+		strcmp((&zo->op2)->u.constant.value.str.val, 
"__BCOMPILER__FILE__") == 0 
+		) {
+			BCOMPILER_DEBUG(("REPLACING 
__BCOMPILER_FILE__ BACK" )); 
+			(&zo->op2)->u.constant.value.str.len 
= strlen( 
BCOMPILERG(current_filename));
+			(&zo->op2)->u.constant.value.str.val 
= estrdup( 
BCOMPILERG(current_filename));
+		}
+
+
+
+
+
 	DESERIALIZE_SCALAR(&zo->extended_value, ulong);
 	DESERIALIZE_SCALAR(&zo->lineno, uint);
 }
 [2010-10-20 08:03 UTC] alan at akbkhome dot com
(it's a patch to bcompiler.c)
 [2010-12-03 08:37 UTC] val@php.net
This bug has been fixed in SVN.

In case this was a documentation problem, the fix will show up at the
end of next Sunday (CET) on pecl.php.net.

In case this was a pecl.php.net website problem, the change will show
up on the website in short time.
 
Thank you for the report, and for helping us make PECL better.


 [2012-10-25 12:04 UTC] rccoros at gmail dot com
It seems that this is still not working in bcompiler-1.0.2.
I am using PHP 5.2.17 and compiling it in a 32bit linux environment.

It is still using the value of __FILE__ at compile time instead of execution time.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Nov 01 20:01:29 2024 UTC