Add PHP generated errors in error log - php

I have this code here to create error log:
error_log(date("[Y-m-d H:i:s]:")." You messed up!", 3, "../my-errors.log");
Here, we can see the custom error 'You messed up!' that I have set to print in the error log. I don't want to use the custom error here. Instead of this I want to set the Errors/Warnings/Notices that are generated by PHP itself.
Is this possible and how can we do that?
Thankyou

if I understood it well, you're looking for error_get_last():
array error_get_last ( void )
error_get_last — Get the last occurred error. / Gets information about the last error that occurred.
Take a look:
$last_error = error_get_last();
$formated_last_error = sprintf('%s in %s on line %d'.PHP_EOL,
$last_error['message'], $last_error['file'], $last_error['line']);
error_log(date(DATE_ATOM) . $formated_last_error().PHP_EOL, 3, '/tmp/logs.log');
However, you should take a look at set_error_handler() function which is a general approach.

Related

PHP code example of exception handler for mysqli errors [duplicate]

PHP is famous for displaying ugly error messages, though they are useful at times. I know I can hide error messages with
error_reporting(0);
That's fine, but it leaves the user completely in the dark as to what is going on. The page has stopped working and they don't know why. How can I display a simple message along the lines of "Sorry, there is an error. Please send an e-mail to the webmaster"?
It would be the same message for all errors, and I'm thinking of maybe popping up a javascript alert, but open to any other ideas.
Implement an error and exception handler
You need to write a custom error handler like this. As you can see at the bottom, I am introducing a FATAL error. Here PHP does not spit any ugly error messages as you have quoted. It would just print Some Error Occured. Please Try Later.
<?php
set_error_handler( "log_error" );
set_exception_handler( "log_exception" );
function log_error( $num, $str, $file, $line, $context = null )
{
log_exception( new ErrorException( $str, 0, $num, $file, $line ) );
}
function log_exception( Exception $e )
{
http_response_code(500);
log_error($e);
echo "Some Error Occured. Please Try Later.";
exit();
}
error_reporting(E_ALL);
require_once("texsss.php");// I am doing a FATAL Error here
There are some rules that should apply to production servers:
Never show them the original PHP error message! Set display_errors = off.
Log those errors. Set log_errors = on and define a valid log target in error_log.
Monitor the error log, and act upon it. :)
The handling of errors to the user side has been sufficiently answered by the others.
You can write custom error handler that does it
http://php.net/manual/en/function.set-error-handler.php
This is typically done via Exceptions. If something goes awry, you'd throw an Exception and then "handle it" with an exception handler.
function exception_handler($exception) {
echo "Oops! Something went wrong! We're looking into it!";
}
set_exception_handler('exception_handler');
throw new Exception('Uncaught Exception');
You can also catch a number of fatal errors by using register_shutdown_function.
set_error_handler might also tickle your fancy.
User custom error handling set_error_handler
and exception handler set_exception_handler
and there you can do what ever you like.

SOAP empty envelope. How to handle empty responses

I am working for a while now with the SOAP API (self teached during work projects). But one thing always bothers me, is that I can't figure out how to handle an empty response.
For instance: I call the service to get some articles from an ERP system. The input parameter is the article number or the GTIN.
Here is some sample code: https://codeshare.io/5e3EYr
If for instance no GTIN is set (just for understanding) the response is not an array anymore (single or multidimensional). The return would be a soap error like "Fatal error: Cannot use string offset as an array" Because the return is the error message.
I hope you understand my problem. I already tried to check if it is_array and even tried to catch the string. But I always get the "Fatal error: Cannot use string offset..." message.
Something like ( as an example for my comment )
function handleShutdown(){
$lasterror = error_get_last();
if (is_null($lasterror)) {
//normal shutdown
return false;
}
//return error to client as XML, JSON etc.
// $lasterror['message']
// $lasterror['type']
// $lasterror['file']
// $lasterror['line']
}
register_shutdown_function('handleShutdown');
I will leave it up to you on how you want to format the error message. The shutdown handler can even catch out of memory errors ... :)
Obviously, you cant catch anything before it's registered so do it early in execution.
php.net/manual/en/function.register-shutdown-function.php
You may also want to look at
set_error_handler
set_exception_handler
Then you can have the trifecta of error handling.
You could use set_error_handler to catch these but you would want to filter out errors of certain verities (in the error handler), an example would be Deprecated or Notice level errors. You can do this with checking the Severity against the error_reporting level you have (bitwise) like this
if($severity & error_reporting())
//report on these errors.
Notice the single & is a bitwise comparison and differs from the normal AND (&&)
Now if you want to prevent the error altogether, I would need to see the code (including the line - marked somehow) where it is produced. Otherwise it's just wild guessing.
In any case when building some kind of service that lacks the normal GUI, it never hurts to have shutdown recovery to send feedback to the client, just make sure to sanitize any output information you share with clients. That way you don't "leak" information that may give away any information that could be used to compromise your application.
cheers.
Finally I figured out, which part to check for an array. If it is not an array, nothing happens. And if, everything is fine.
if(is_array(['getSomeArticleResult']['SqlRowSet']['diffgram']['SqlRowSet1'])){
$aSuppl = $aSuppl['getSomeArticleResult']['SqlRowSet']['diffgram']['SqlRowSet1']['row'];
return $aSuppl;
}

Handle errors from external library (simple_html_dom)

I'm building a page to crawl some web pages.
It works, usually, but everyone once in a while, it will fail to grab the page, and throw the following error:
( ! ) Warning: file_get_contents(URLWASHERE): failed to open stream: HTTP request failed! HTTP/1.1 404 Not Found in Z:\Wamp\www\spider\simple_html_dom.php on line 555
Here is how I'm grabbing the page:
$page->load_file('URLWASHERE');
Is there a way to figure out if that error happens? I don't know how to detect it because it's in the library, not my code.
I can't use if (!$page) because it still returns something. But that something doesn't seem very helpful, though it is significantly shorter.
You can see output here:
$page when successful: http://pastebin.com/CnRVP6SK
$page when failed: http://pastebin.com/t9q6Gwnf
I just want to be able to find out if there was an error so I can have my program try again.
You can use the error_get_last() function to get info about the last error. You might also consider silencing the warning message with the # operator.
#file_get_contents('http://example.com/wjqlshqwd');
$error = error_get_last();
if($error && strpos($error['message'], '404') !== false)
{
echo 'There was an error';
}
Also before running this code you should reset the state of error_get_last(), a comment on the PHP manual page describes a trick to do that:
// var_dump or anything else, as this will never be called because of the 0
set_error_handler('var_dump', 0);
#$undef_var;
restore_error_handler();
// error_get_last() is now in a well known state:
// Undefined variable: undef_var
The concept is just to create a known error.
It seems I can use
if(error_get_last())
to check if an error has been thrown so far.
This will break if other errors are encountered, but my code seems to be free of errors aside from this occasional one, so I will use this.
unfortunately, this will only allow me to try twice, rather than keep trying until it works.

User-Friendly PHP Error Message

PHP is famous for displaying ugly error messages, though they are useful at times. I know I can hide error messages with
error_reporting(0);
That's fine, but it leaves the user completely in the dark as to what is going on. The page has stopped working and they don't know why. How can I display a simple message along the lines of "Sorry, there is an error. Please send an e-mail to the webmaster"?
It would be the same message for all errors, and I'm thinking of maybe popping up a javascript alert, but open to any other ideas.
Implement an error and exception handler
You need to write a custom error handler like this. As you can see at the bottom, I am introducing a FATAL error. Here PHP does not spit any ugly error messages as you have quoted. It would just print Some Error Occured. Please Try Later.
<?php
set_error_handler( "log_error" );
set_exception_handler( "log_exception" );
function log_error( $num, $str, $file, $line, $context = null )
{
log_exception( new ErrorException( $str, 0, $num, $file, $line ) );
}
function log_exception( Exception $e )
{
http_response_code(500);
log_error($e);
echo "Some Error Occured. Please Try Later.";
exit();
}
error_reporting(E_ALL);
require_once("texsss.php");// I am doing a FATAL Error here
There are some rules that should apply to production servers:
Never show them the original PHP error message! Set display_errors = off.
Log those errors. Set log_errors = on and define a valid log target in error_log.
Monitor the error log, and act upon it. :)
The handling of errors to the user side has been sufficiently answered by the others.
You can write custom error handler that does it
http://php.net/manual/en/function.set-error-handler.php
This is typically done via Exceptions. If something goes awry, you'd throw an Exception and then "handle it" with an exception handler.
function exception_handler($exception) {
echo "Oops! Something went wrong! We're looking into it!";
}
set_exception_handler('exception_handler');
throw new Exception('Uncaught Exception');
You can also catch a number of fatal errors by using register_shutdown_function.
set_error_handler might also tickle your fancy.
User custom error handling set_error_handler
and exception handler set_exception_handler
and there you can do what ever you like.

Suppressing errors in PHP

I'm running a PHP script every night using a cron service. Everything it outputs will be printed to an log file for debug prepossess. The file I use will retrieve xml's from a different site using the function 'file_get_contents()'. But the function can return an error which I really don't want to see as I am already showing a custom error.
Quick example of my piece of code:
$buffer = #file_get_contents('http://xx:xx#xx/xml/xx?offset=2') or print('retry in 5 seconds');
if($buffer === false) {
sleep(5);
$buffer = #file_get_contents('http://xx:xx#xx/xml/xx?offset=2') or print('error notice');
}
The problem is the first one will trigger an error and print it'll retry in 5 seconds. How can I correctly suppress the thrown error?
I have an error handler, but I prefer not to catch this error separately.
Edited:
My solution wasn't to change the error_reporting, but to catch the error message. If it starts with 'file_get_contents()', no error will be thrown. This is not the best way, but will do the job for me.
You can try inserting this at the start:
error_reporting(0);
Then after the code with the error/warning:
error_reporting(E_ALL ^ E_WARNING);
Okay, never ever use the #-operator.
In PHP you have two options available: either use a custom error handler or use try/catch.
Since file_get_contents doesn't throw an exception, you can only use the first approach.
You can set an error handler like this: http://php.net/set-error-handler and then act correctly (log something or return a custom error code).
If you just want to turn of all errors use error_reporting(0) or if you just want to turn off a specific category use error_reporting(E_ALL ^ E_WARNING) (all but warnings) or specifcy them explicitely error_reporting(E_WARNING | E_NOTICE) (warnings and notices).
I prefer the first approach, since when you just disable it you have no idea of what's going on in your code.
Add # before command or use try catch.

Categories