问题
I'm programming PHP for some time.
I use an Windows XP SP3 with PHP 5.4, SQlite 3, Apache 2.4 as a development environment. The remote host server (not mine) is a Windows Server 2008 with PHP 5.3, Apache 2.2, IIS 7.0 and SQL Server 2008.
My editor is the simple and wonderful EditPlus.
Concerning Javascript it's nice because of Firefox plus the great add-on FireBug, which allows for complete HTML + CSS + Javascript debugging.
My problem is PHP error management in my development environment (my personal machine).
The PHP syntax errors typically appear ok with line number and so on, allowing easy fix. Also there are online tools for check syntax (e.g pilliap) and other online tools to test the execution of PHP snippets (E.g writecodeonline.com )
However, my curse is runtime errors (eg, uninitialized variable $ _SESSION). Sometimes it shows correctly, but other times the error message (including the right line number!) are embedded within the source code, inside spurious HTML tags. Simple tests shows no problem. but my real code generally does.
It is not a situation that does stop me from moving forward, but it is unpleasant.
I did not find any hint on the Internet about this strange behavior and I'm very curious if somebody can give a clue about it.
My question: How is possible a PHP runtime-error sometimes appears in the browser (as desired in a development environment), sometimes it appears inside Javascript + HTML source code together spurious HTML tags?
PS: Is not a question about PHP log files or Display Error setting in PHP.Ini file.
PS2: The same situation happens with or without XDebug installed.
回答1:
Use the php error_log()
function to show information about your errors the way you want.
Apart from that, have a look at your php.ini
configuration file. There are many variables (html_errors
, error_log
, display_errors
, error_reporting
...) to setup the output of errors as you want so they not mess up the html output.
回答2:
This is what the log_errors
and the error log file are for. Just read them and all of your errors are nicely listed.
EDIT: You can also drag all errors on the page to be visible with the following:
First, set error_prepend_string
and error_append_string
to something noticeable. For instance, you can use <phperrormessage>
and </phperrormessage>
. Just anything that is unlikely to appear in your legitimate output.
Then place this at the start of your code:
ob_start(function($c) {
if( preg_match_all("(<phperrormessage>(.*?)</phperrormessage>)is",$c,$matches)) {
$c = preg_replace("(<phperrormessage>(.*?)<phperrormessage>)is","",$c);
$c = str_replace(
"</body>",
"<div id=\"phperrors\">".implode("<hr />",$matches[1])."</div></body>",
$c);
}
return $c;
});
回答3:
Forums and Q&A websites are indeed a great resource for learning! Thanks Kolink and StackOverflow.com.
From the Kolink tip, I've researched a little bit and then I've created a new way to tame the vast majority of runtime errors in PHP.
I have not figured out exactly what is happening, but I've discovered a powerful way to not use the default PHP error-handling and instead collect all runtime error messages in the same place.
Note that the PHP compilation errors are not a problem for me, because any syntax checker solves it, including PHP.exe.
Suppose I have a PHP source code with many potential runtime errors. So I put my code in the following lines inside HTML tag, e.g. in the initial position that I need use PHP code.
<script type="text/javascript">
var nerrors = 0; // PHP Errors count in Javascript
function PHPErrors() { // Javascript Function that wraps the PHP Code
<?php
// MyErrorHandler is my function that my custom error handler
// uses with error parameters in that given order.
function myErrorHandler($errno, $errstr, $errfile, $errline) {
echo "document.getElementById('PHPErro').innerHTML += " .
"\"$errno: $errstr ($errline)<br>\";\r\n";
echo "nerrors = nerrors + 1;\r\n";
return true;
}
// That's the line the set my custom new error-handling
// disabling the default error handling
$old_error_handler = set_error_handler("myErrorHandler");
// Below random PHP code full of errors
$b = $a; // PHP Error 1
$c = $a +1; // PHP Error 2
$d = $a + 1; // PHP Error 3
$e = $_SESSION['glove']; // PHP Error 4
?>
// No PHP runtime error deserves a nice messagen
if (nerrors===0) {
document.getElementById('PHPError').innerHTML =
"Well done! PHP without errors."; }
} // End Javascript Function
After this code one can put additional Javascript and PHP freely.
Finally I put in my some place inside HTML body part this 2 lines.
<p id="PHPError"> </p>
<button onclick="PHPErrors()">Show me all PHP runtime errors</button>
When I browse this PHP page, I can see this button. So I press it and I can see all PHP runtime error messages or the pleasant "Well done ... " message.
回答4:
Finally I've discovered what happens with PHP.
The default PHP error handling generates errors in the body section. With XDebug the message is more detailed, but the same situation happens.
So when I put PHP code inside a JS function, before BODY section, this behavior doesn't work, because HTML tags before BODY section generates garbage.
Syntax errors are different because it is a previous phase from PHP interpreter, that is made before running the PHP + HTML code.
Therefore, to be possible to examine the error, In that case you need to look the source code. There will be the spurious tags with the error message.
So my code in other Q&A that I've posted in StackOverflow deals with that situation.
回答5:
I have the same problem.
I tried your solution with limited success. I actually like my original error handler - it sends an email. When I used to build pages with just php, I found that I did not need to send an email as the error would just show up nicely. Now that I am moving to javascript rendering of html, the error does not show up, or is hidden. The logging is kinda painful to navigate to, page source is better, but my email is always open. It builds an error message and emails it as well as echo
the message, but as we know this is dumping to the page source and not showing up or sometimes showing up in bits.
function pos_error_handler ($e_number, $e_message, $e_file, $e_line, $e_vars)
{
$includes = get_included_files();
//var_dump( $includes);
//echo 'WTF';
// Build the error message.
$message = "<p>Nice Job moron: A pos error occurred in script '$e_file' on line $e_line: $e_message\n<br />";
// Add the date and time:
$message .= "Date/Time: " . date('n-j-Y H:i:s') . "\n<br />";
// Append $e_vars to the $message:
$message .= "<pre>Error Variables:<br />" . print_r ($e_vars, 1) . "</pre>\n</p>";
// what is the url?
$message .= "<p><pre>URL: " .getPageURL() . "</pre>\n</p>";
$message .= '<pre>Session variables:<br />' . print_r($_SESSION,1). "</pre>\n</p>";
$message .= '<pre>Bactrace:<br />' . print_r(debug_backtrace(),1). "</pre>\n</p>";
if (!LIVE)
{
// Send an email to the admin:
mail(SUPPORT_EMAIL, 'TEST Site Error!', $message, 'From: ' . SUPPORT_EMAIL);
// Development (print the error).
echo '<div class="error">' . $message . '</div><br />';
}
else
{
// Send an email to the admin:
mail(SUPPORT_EMAIL, 'Site Error!', $message, 'From: ' . SUPPORT_EMAIL);
// Only print an error message if the error isn't a notice:
include(HEADER_FILE);
if ($e_number != E_NOTICE)
{
echo '<div class="error">A system error occurred. We apologize for the inconvenience.</div><br />';
}
echo '<div class="error">An Error has occurred and has been emailed to the administrator. Please note the conditions that caused this error and send a note to the administrator</div><br />';
}
//include(FOOTER_FILE);
exit();
}
来源:https://stackoverflow.com/questions/14348252/php-runtime-error