This may be too obscure of an question, but I've been troubleshooting a baffling server error for hours and have pinned it down to the most bizarre issue; at this point I just want to know if anyone has ever had something similar occur, or might have any insight into what might possibly be happening.
The following line of code is triggering the error:
if ($Name=='ProxiedIP') { return true; }
This version runs without any problem at all:
if ($Name=='proxiedIP') { return true; }
It seems like somehow the token 'ProxiedIP' is fouling something up, but I cannot even think of how a string literal would be translated by the parser in a way that could hang the server up like this. BTW, I know for certain that $Name!='proxiedIP' and $Name!='ProxiedIP'.
Here's the entry in the apache error log:
[Fri Jan 18 18:15:12.924419 2013] [core:error] [pid 27676:tid 3427232831232] [client 12.345.67.890:34482] Premature end of script headers: index.php, referer: http://mySite.com/
I searched for 'ProxiedIP' as a keyword for every component that I can think of on my system and I'm coming up with nothing. The more imperative question for me though is how a string could somehow have this impact in a comparison check. Any ideas?
Also noteworthy that the PHP error log is completely silent about it. I'm enabling error output at the top of the page, but the script never finishes loading so that may be a factor. Here's how I'm setting it:
error_reporting(E_ALL);
ini_set('display_errors', 1);
Because the code worked here, it seems more likely that it could be something specific to the platform implementation. I'm running this on an instance of Gandi.net's 'Simple Hosting' service, which runs Varnish for application acceleration. It may also be worth mentioning that the code is being loaded in an iframe in a separate domain.
I am also doing some intensive work with the headers, and this seems like the greatest potential source of the problem, although the strange thing as far as I'm concerned is the way the error is being triggered. Also, there's no common header that I'm aware of called 'ProxiedIP', although that use conflict is the only thing that seems like it could make sense so far. Regardless, I don't see it.
To me, the real item of relevance is the mere fact that a string comparison is crashing the server. I've been programming in PHP for over 10 years and I have never had anything like this happen before. I'm trying to understand the logistics behind how it could even happen.
Update: I've tried the following variation, and it still produces the same result:
if ($Name === (strtoupper("p").'roxiedIP')) { return true; }
It was asked whether I would post the full code, but the script for the iframe side is 1400+ lines long so that's not really feasible. I'm adapting the segment in question to try running it in a new script though and will post the results.
I think the problem is with the variable $Name. Check whether it is getting assigned properly. Also check the code after if statement which is causing the problem.
Actually, I think your problem lies in the calling function, i.e. depending on the return value it does something "stupid" and PHP crashes.
Try replacing the if() with a hard return true or return false and see what happens.
As i get from your error, you are messing up the framework, the change in that if of yours triggers some output being called before the fw is allowed to make output. Just read it in more detail, you got it on the wrong train, that is not the cause of the error, it is the beginning of an unhallowed state of the fw.
Try running the script in a php debugger rather then using var dump.
Thanks for the posts, but it turned out to be a really convoluted scenario, where conditions several levels down the function chain caused unexpected behavior outside the scope of either function in question.
The actual issue was due to a condition check while parsing through output of a debug_backtrace() array in a totally separate process, which ironically was in place to prevent infinite recursion and instead triggered a similarly disruptive cascade of events that overran the allocated memory limit.
I originally posted because I was baffled by what truly seemed to be a string literal comparison doing something I didn't think should be possible, and wanted to understand what conditions could allow it to happen if so. I'm just glad the cause wasn't actually what it seemed to be. Thanks for helping to solve the puzzle.
Update: The true source of the error hinges on PHP's difficulty translating objects or arrays that contain references to themselves. I'm storing converted headers, direct header references, $_REQUEST[] and $_SERVER[] items, as well as logging messages and associated data in complex associative arrays. There are a lot of dynamic references between these items, particularly those involving the native PHP globals which I've made use of.
PHP has traditionally had problems managing self-referencing entities, and although improvements have been made, my particular situation is complex enough to send ReflectionClass into an endless loop while attempting to map these objects. I've fixed it by manually dereferencing the items as I'm polling them, but it's something to be aware of if needing to work with multiple $GLOBALS-related vars within a common array or referencing structure.
Related
First of all - there seem to be many questions about the fundamentals of tick functionality, so I want to add the top user comment at php.net/declare to the pile for anyone looking for further information. I found it while digging around as I tried to figure out the following.
So, I'm working on writing a simple debug helper. I want to add function tracing and benchmarking - basically what tick functionality is perfect for.
Thing is, I want to enable and disable benchmarking depending on arbitrary conditions that occur during script processing. I'm not really looking for fixed debugging à la scoped declare() { ... }.
What I'm looking to do is to put declare(); at the top of my script, and then register and unregister my debugging/benchmarking (tick) function as appropriate. Un/registration won't happen (too) often, so is efficient and reasonable.
But then I got curious: when I don't have a tick function registered... does the fact that I've run declare(ticks=1); have any effect on execution efficiency? Does it cause any extra processing to become permanently enabled anyway?
Analysis of PHP(7)'s source code shows that the answer is technically yes, but I'm not yet sure how.
The answer seems to be in zend_compile.c:8200: it appears this function defers compilation processing to the appropriate routines, then if ticks are enabled it additionally emits a ZEND_TICKS opcode into the opline via zend_emit_tick() in :2167. The opcode reference page for TICKS seems consistent with this conclusion; it shows an example disassembled opcode listing which has TICKS opcodes scattered throughout it, and I was wondering how they got in there until I discovered the above.
The ZEND_TICKS handler (in zend_vm_def.h:6859) seems to call zend_ticks_function(). This is mapped to ticks_function() in zend.c:754, which is in turn mapped to php_run_ticks() in main.2013. This is finally defined in php_ticks.c, where it's all of:
void php_run_ticks(int count)
{
zend_llist_apply_with_argument(
&PG(tick_functions),
(llist_apply_with_arg_func_t) php_tick_iterator,
&count
);
}
Huh. Not bad.
But here's the thing. If I declare(ticks=1);, the above dispatch is being run for literally every statement executed. That's... ouch. For long-running scripts containing high-iteration-count, tight processing loops, I'm wondering how badly that'll add up.
Problem is, I'm not even sure how to benchmark this. The only way I could envisage to do so would be to synthesize some PHP bytecode and then figure out a way to inject that directly into the PHP bytecode interpreter.
And that leads to my question: how much of a performance impact does this additional dispatch have, in practice? How can I quantify it?
Obviously the above investigation was performed on the canonical PHP.net interpreter. I haven't looked into how HHVM does this at all (yet), but I wouldn't at all mind learning how it handles it.
I have built a robot which basicaly crawls websites starting at the root, parses the page, saves all the internal links, and then moves to the first page in the link list, parses it and so on.
I know its not really optimized to run this sort of bot in PHP but as it's the only language I happen to know well enough, thats the one I chose.
I came accross all sort of issues : pages returning 404, then pages being redirected then pages which are not parsable (werid case of few pages that return a few words when being parsed but return the entire expected body when you send a GET http request), etc...
Anyway I reckon I have made the robot so it can go through 99.5% of the pages it parses, but yet there are some pages that are not parsable and at that point my bot crashes (about 1 page out of 400 make the bot crash, and as crashing I mean, I just get a fatal error, the code just stops then).
Now my question is : how can I prevent this from happening ? I am not asking how to fix a bug I cant even debug (they re most of the time times out, so not very easy to debug), I'd liek to know how to handle those errors. Is there a way to refresh the page in case a certain type of error occurs ? Is there a way to go around those time out fatal errors ?
I cannot see the point of showing you any sort of code, although i will if you feel the need of checking a certain part of it.
Thank you
Simplest way I can think of is to use a try{} catch(){} block.
[http://www.php.net/manual/en/language.exceptions.php][1]
You put the part of the parser into the try block, and if an error is thrown, feed some default values and go to the next link.
If you are getting fatal errors (which I think you can't catch with try), then you could also try to break each step download/parsing into a separate php file that is called with the url it needs to lookup via curl. This kind of poor man's parallelization will cause you to incurr a lot of overhead though and is probably not necessarily how php "should" be used, but should work. You'll also need to store the results in a database / text file.
Scenario:
We are in the process of converting an application from PHP 4 to PHP 5. The application needs to be able to work on PHP 4 for a little while, which means no PHP 5 specific elements can be used, yet. We are simply trying to make sure the application works on both platforms.
There are a lot of conditionals that look like this in the application:
if ($variable) { // do something }
Some of these variables end up not being defined at all and we are trying to reduce the number of errors (there's a lot of them).
To solve these errors, we are adding checks in various areas like this:
if (!isset($variable)) $variable = "";
or
if (!empty($variable)) { // do something }
Question:
Does anyone know of a simpler approach to fixing these errors. The problem is that these variables are being used across files (via includes) and defining the variable may change the logical flow in that file if its doing a check like (if (!isset($variable)) { // do something }).
The point of this question is to reduce errors and time consumption of tracking each individual use of these variables. Currently, we are having to either examine thoroughly what the variable is doing (which may take a good chunk of time), or we are doing a "fire and forget" / hope-its-fixed method of correcting.
-- Edit --
Does anyone know of a program like cppcheck for php that could somehow reference these variables or create some kind of chaining that could find errors and link possible references? (I hope that makes sense.)
AFAIK there is a code-checker that looks for uninitialized variables which works OK. You can work through it's messages, it's called PHP Mess Detector and one of it's rule covers uninitialized variables. However this can never be perfect.
Another method is to track the error messages and use them to locate the places within in the code. I've done that in the past and it worked very well, just do it in iterations and keep log of the warnings.
You can also work with a whitelist and import whitelisted variables when the request starts. Non-whitelisted submissions need to cause an access violation error to have this properly working, so this way is more work than tracking warnings albeit it might make your application more secure.
Please see as well:
PHP Syntax checking pre-source control
E_NOTICE ?== E_DEBUG, avoiding isset() and # with more sophisticated error_handler
isset() and empty() make code ugly
I am working on a website with a few friends, and recently, users have complained about a fairly important feature doing nothing but return a blank page. This only happens for some users, while other users are able to use it perfectly fine.
I consulted debug output and it turns out that a function is being declared twice. Once in the feature's main page (foo.php) and one in a file that gets require_once'ed. Obviously I'm on the right path to fixing it now, but what confuses me is that many people do not get this problem when visiting the page. Both function declarations are identical; the bodies seem to have been copy+pasted from one file to the other. Neither of these function declarations are conditional; they should both always take place.
Does anybody know of situations where PHP will be able to handle my mistake and make the page work anyway, despite this fatal error?
it may be the type of your function declaration is public,private or protected so that you might be not getting fatal errors by luck as till to my knowledge php does not allow function redeclaration in or by any means .
Sorry, PHP can never ignore fatal errors or function redeclarations, because in that cases, PHP will be confused as to what function declarations to consider, whether to use a old declaration or a new declaration.
Fatal Error means, there has something is so wrong, that PHP is confused as to what to do next, and therefore its your job to do it right.
Sorry PHP wont try to figure out as if two or more declarations were same and then ignore one of them. If this had to be done, the already slow PHP will become even more slower. So in the interest of community, you should consider writing a correct code, rather then asking PHP interpreter to correct this for you.
I have turned on error_reporting(E_ALL) and run this code:
$topic_id = (int) safe_query($_GET['top_id']);
if($topic_id > 0)
include("topic.php");
And get this error: Notice: Undefined index: top_id. Is it that bad what I do? If yes then why? Should I check if $_GET['top_id'] isn't empty before I give its value to $topic_id? Why? Thank you.
One of the reasons why I do it is to prevent unexpected behaviours.
Code should always reflect the intention of the programmer. If a behaviour depends on some mysterious process in the background, eventually it will come and bite you in the ass when you are knee deep within bugs and debugging.
Traditionally, attempt to access an array with a key that doesn't exist causes a crash (probably in unmanaged environment) or an error. PHP silently 'fixing' this in background is great for beginners, but bad for debugging. Your code will work, but may give you unexpected result.
Take for example, your code. Say the calling page forget to specify the top_id, or misspelt it as topid, and PHP goes on its merry way. It didn't include topic.php, and nothing happens. The code works fine. PHP doesn't complain. What's wrong?
Now, your code is short. What happens when it is longer? Nested deep within many lines, between different functionalities? For your case it isn't a big deal, but when doing complex array manipulation it will make debugging harder.
I understand the question now. I'd suggest using isset just to be safe. I'm assuming you don't have a topic_id that is 0.
It's not really a problem here, since you only take action on it if it's set anyway. However, you're just lucky that the unset value evaluates to false. Also, it'd be annoying to continue having it give you the warning. You'd probably be best suited by doing what others have suggested, checking if it's set before using it. It might be easiest to just set up a function that does that, especially if you're going to be checking a lot of GET parameters.
Whatever you do, don't just turn the warning level down to suppress the warning; in this case, it doesn't hurt to assign from the unset variable, but in the future it could indicate an actual error.
"And get this error ... Is it that bad what I do?"
Well, it's not giving you an Error. It's giving you a Notice. Notices are "ignored" (that is, not echoed) on production servers.
Essentially, PHP is telling you what Extrakun is saying in his answer. You should take notice to a potential mistake that could lead to a real error later.
So, "Is it that bad what I do?" ... maybe not. But, then again, PHP is also not giving you an error. It is giving you the right amount attention that the code segment deserves - a Notice.