|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
[2011-08-06 22:00 UTC] gopalv@php.net
[2011-08-07 06:27 UTC] phpbugs at colin dot guthr dot ie
[2016-11-18 21:38 UTC] kalle@php.net
-Status: Open
+Status: Wont fix
[2016-11-18 21:38 UTC] kalle@php.net
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Wed Oct 29 00:00:01 2025 UTC |
Description: ------------ Hi, This is a self confessed weak bug report as although I can reproduce the problem reliably, I cannot come up with a reliable test condition that exhibits this problem, but from poking around at it a lot, I *think* I've got a rough explanation. Now, I don't know the internals of APC very well, so the term "jump point" may not be valid and thus throws the whole of this report into doubt, but I'll try my best with the description and see if those cleverer than myself can clarify. What seems to happen in this case relates to variable scope, a require() statement (no require_once) and a conditional function definition inside that required file (it's conditional to work around the fact that the file is require()'ed rather than require_once()'ed). When this happens, it seems that the code being executed is not correct. It seems to that when the conditional function is called, the bit of code that is in that file after the function definition is also executed. Reproduce code: --------------- I'll demonstrate the layout here (although this code does not exhibit the problem on it's own): File1 (index.php): <?php class apcParams { function def($name, $value) { $this->$name = $value; } function get($name) { return $this->$name; } } class apcBug { public static function myInclude($file) { $params = new apcParams(); $params->def('Something', 'Wicked'); $params->def('ThisWay', 'Comes'); require($file); } public static function doCallback(&$params, $callback) { $callback($params); } } apcBug::myInclude(dirname(__FILE__).'/includee.php'); ?> File2 (includee.php): <?php if (!defined('apcFuncDefined')) { function apcFunc(&$params) { echo "In callback: ".$params->get('Something')."<br>"; } define('apcFuncDefined', true); } apcBug::doCallback($params, 'apcFunc'); ?> Expected result: ---------------- Here, the index.php file require()'s the includee.php file. When it calls require() a variable ($params) is in the scope. This variable is used inside includee.php. It ultimately prints out "In callback: Wicked". Actual result: -------------- The problem I experience with a much more convoluted code base is that there are occasions when $params variable is simply not set inside the file. This initially made me believe that there was some kind of scoping problem inside APC relating to "require" calls or similar, but with further investigation I do not think this is actually the case. The reason I do not think it is a scoping problem relates to the use of a work around I put in place. Rather than set a local variable, I instead set a GLOBAL (actually I used more of a registry model, but the principle is the same). When this happened, I ended up with infinite recursion (900 calls at least on the stack!). As there was definitely no recursion actually written in the code, this seemed to indicate that the line in includee.php that calls apcBug::doCallback() was simply being called whenever the callback function was being called.... this in turn led to the recursion. Obviously, this should not be the case and the fact that that code was being run was an error. I think it is this that is the fundamental problem here. I think that there must be some kind of error in the "entry point" into that required file due to the conditional definition and rather than calling the callback, it is just landing and executing the static code. If I replace the conditional function definition with a require_once and put the function in a separate file, it appears to work around the problem (can't say for certain but I have not been able to reproduce it yet) which gives further credence to the above hypothesis. I am on x86_64 but have had seen the same symptoms on i586 boxes too. It is an intermittent issue even when it does occur but with our codebase I can generally reproduce it in a few clicks. I appreciate that without a good reproduction case, this may be a very tricky bug to nail down, but I live in hope that this description will be sufficient to maybe spark a few thoughts.