ZendFramework Log Errors - php

I'm trying to log all application errors easily. Does ZendFramework have a plugin that can do this, or can it do this natively?

Type in your configuration:
phpSettings.log_errors = 1
phpSettings.error_log = "/path_to_yours_application_logs/php.log"
This puts all error logs to php.log file. It's common approach in production environment.

Zend includes standard error handling plugin that redirects to ErrorController.
Here are 2 solutions:
Create Zend_Controller_Plugin_ErrorHandler and register in bootstrap/controller
Create custom PHP error handler

also you can use in your Controller
try{
} catch(Zend_Exception $e){
echo $e->getMessage
(or log errors in log file using Zend_Log)
}
Zend_Log
Zend_Exception

To log all Error types (also PHP Fatal Error):
register_shutdown_function( 'myErrorHandler' );
function myErrorHandler() {
$error = error_get_last();
if( $error !== NULL) {
getMyZendLogger->log("got error: ".$error["message"], Zend_Log::ERR);
}
}
See How do I catch a PHP Fatal Error
Zend_Log::registerErrorHandler() (Zend-FW 1.12) catch not all errors

Related

Laravel Turn Off Exception Handler [duplicate]

This question already has answers here:
Disable Laravel's built-in error handling methods
(7 answers)
Closed 1 year ago.
In Laravel, whenever there error, even minor NOTICES, WARNINGS and DEPRECATED erros, I got the full debug info which kills the application. In my App.config I've turned debug => false and I get the message of 'Whoops, looks like something went wrong.'
How can I turn off all error handling but Laravel to just get normal PHP errors that do not interrupt the entire flow of application?
If you don't want to interrupt your workflow for certain PHP error types, you will need to disable the error handler registered by Laravel for those errors.
Laravel registers its error handling in Illuminate/Foundation/Bootstrap/HandleExceptions.php. This bootstrapper is one of several that is called when your Http kernel handles a request.
While there are a couple ways to do what you want to do, I think the easiest is to handle the event that is fired after this bootstrapper is called. In the event handler, you can reset the error handler for the errors you don't want Laravel to process.
In your bootstrap/app.php file, add the following line right before $app is returned:
$app->afterBootstrapping(
'Illuminate\Foundation\Bootstrap\HandleExceptions',
function ($app) {
set_error_handler(function ($level, $message, $file = '', $line = 0, $context = []) {
// Check if this error level is handled by error reporting
if (error_reporting() & $level) {
// Return false for any error levels that should
// be handled by the built in PHP error handler.
if ($level & (E_WARNING | E_NOTICE | E_DEPRECATED)) {
return false;
}
// Throw an exception to be handled by Laravel for all other errors.
throw new ErrorException($message, 0, $level, $file, $line);
}
});
}
);
The App\Exceptions\Handler.php file is built just for this.
In the public function render() method, you can catch applications and perform certain redirects/page views if you so choose:
For instance, you can capture HttpException's in your application and then return an error page if you wished:
public function render($request, Exception $e)
{
//other stuff
if ($e instanceof HttpException) {
return view('errors.general')->withErrors([
'message' => 'The application encountered an error!'
]);
}
return parent::render($request, $exception);
}
That up-voted answer is the opposite of what he asked.
As far as I can tell, there isn't a way to separate error reporting and laravel taking over rendering of the screen. I've been looking through the Laravel 5 code and haven't found a way to split them apart using their setup yet.
You could write your own library to totally take over all error handling and remove all of laravels internal tracking, but then you'd have to make sure to pass it back to laravel in the cases where you need the orig page error handling. Easiest way would be find a 3rd part error handler vendor then modify it to take over all error handlers and not block rendering.

Would displaying PHP Exception Message be a security risk?

I want to set a custom message to be displayed to the user when I throw an error in Laravel 5.1. For example, in a controller I might have:
if(!has_access()){
abort('401', 'please contact support to gain access to this item.');
}
Then my custom error page I would display the error with:
$exception->getMessage();
However, what if there was a SQL error or other event? Wouldn't that also set the Exception Message which I would be unknowingly outputting on my error page?
The PHP docs for getMessage() don't go into much detail about this.
How can I set a specific exception message without introducing any security risk?
However, what if there was a SQL error or other event? Wouldn't that also set the Exception Message which I would be unknowingly outputting on my error page?
Potentially, yes. PHP makes no guarantees that the contents of exception messages will be "safe" to display to users, and it's quite likely that some classes will throw exceptions which include sensitive information in the message.
If you want to use exceptions to display errors to users, use a specific subclass of Exception for those exceptions, and only print the message if the exception was an instance of that subclass, e.g.
class UserVisibleException extends Exception {
// You don't need any code in here, but you could add a custom constructor
// if you wanted to.
}
// Then, in your abort() function...
throw new UserVisibleException($message);
// Then, in your exception handler...
if ($exc instanceof UserVisibleException) {
print $exc->getMessage();
} else {
print "An internal error occurred.";
}
If you access your app.php file:
'debug' => env('APP_DEBUG', false),
In your production env, set this to false. This would make sure that no debug errors would be displayed in the production environment.
Once this is set, you can respond to normal exceptions through your controller. Anything else, laravel wouldn't display the error page.
Yes,
$e->getMessage() can potentially reveal more information about your code IF you use it in a similar way:
try {
$executeSomethingHereForWhichYouExpectAnException();
// Basic \Exception that reports everything
} catch (\Exception $e) {
$error = $e->getMessage();
}
even with 'debug' => false in app.php. For example if you have an error with your code $error would display it - basically ANY type of error (PHP,MYSQL,ETC);
However, there is a fix - to catch your CustomException messages and prevent typical error displaying if you use it in like so:
try {
$executeSomethingHereForWhichYouExpectAnException();
// Our custom exception that throws only the messages we want
} catch (\CustomException $e) {
// Would contain only 'my_custom_message_here'
$error = $e->getMessage();
}
What is the difference you may ask - the difference is that instead of \Exception which is the basic error reporting, we use \CustomException class, which you throw from $executeSomethingHereForWhichYouExpectAnException() function:
executeSomethingHereForWhichYouExpectAnException(){
if (something) {
throw new CustomException("my_custom_message_here", 1);
}
}
If you have more exceptions you can include them like so (as of PHP7.1):
try {
something();
} catch(\CustomException | \SecondCustomException $e) {
// custom exceptions
} catch(\Exception $e) {
// basic exception containing everything
}

file_exists() failing without safe_mode being on

spl_autoload_register(function ($className)
{
if (file_exists($className . '.php'))
{
require_once($className . '.php');
}
else
{
throw new Exception('Could not load class: ' . $className);
}
});
//Load models and save them in variable instances
try
{
$this->database = new Database (
$config['DB']['HOST_IP'],
$config['DB']['DATABASE_NAME'],
$config['DB']['USERNAME'],
$config['DB']['PASSWORD']
);
//Set the initial language for our template model.
Template::setLanguage();
}
catch (Exception $e)
{
echo $e->getMessage();
}
Script works if I erase file_exists, but file_exists returns false no matter what.
What may be causing this?
Also, I get an error message: Uncaught exception 'Exception' with message 'Could not load class: Template'. Is it because Template class is static?
There are 2 faults with your code.
Instead of meaningful and reasonable system error message you are ecoing just useless and generalized error message which cannot help you
You uare using try-catch just to echo a message. Which is deadly wrong.
So, just get rid of all try-catch blocks in your code and run it again.
And never use try..catch if you're not going to handle an error
instead of that set error reporting to be able to see the error messages
error_reporting(E_ALL);
ini_set('display_errors',1);
The problem was having two extensions on my PHP file. (e.g index.php.php) Sadly, the windows environment wasn't configured so I struggled finding the issue.

PHP: register_shutdown_function does not always work with Symfony 2

I'm trying to 'catch' PHP Fatal errors with register_shutdown_function, just so that I can return a clean error message.
In a simple PHP file, both test cases below are correctly handled and my custom 500 error is returned.
register_shutdown_function('handleShutdown');
//Test Case #1
$nullVar = null;
$nullVar->test();
//Test case #2
$uninitialisedVar->test();
function handleShutdown()
{
$error = error_get_last();
if ($error !== NULL)
{
ob_clean();
header('HTTP/1.0 500 Internal Server Error');
echo 'Something bad happened';
}
}
However, when using the same mechanism from within a Symfony 2 action inside a controller, test case #2 is not handled anymore: my handler is only called when the variable has been initialised before. However, in both cases we are dealing with the same kind of fatal error (call to a member method on a non-object).
Can someone help?
In debug mode Symfony2 calls set_error_handler which may be conflicting with the register_shutdown_function. In production mode it will not happen.

Php mkdir( ) exception handling

mkdir() is working correctly this question is more about catching an error. Instead of printing this when the directory exists I would just like to have it write to a message to me in a custom log. How do I create this exception.
Warning: mkdir() [function.mkdir]: File exists
I would just like to have it write to a message to me in a custom log.
the solution is very easy. PHP already have everything for you:
ini_set('display_errors',0);
ini_set('log_errors',1);
ini_set('error_log','/path/to/custom.log');
or same settings in the php.ini or .htaccess
I think it would be better than write each possible error manually
If you don't want this error to be logged (as it may be not error but part of application logic), you can check folder existence first
if (!file_exists($folder)) mkdir($folder);
else {/*take some appropriate action*/}
You can stop the error message from displaying either by suppressing error messages globally (in config or runtime) with the display_errors setting, or case by case by prefixing the function call with an #-character. (E.g. #mkdir('...')).
You can then check with error_get_last when mkdir returns false.
For error logging global rules apply. You can log errors manually with error_log.
For further reading, see the manual section on Error handling.
Edit:
As suggested in the comments, a custom error handler is also a possible, arguably more robust (depending on your implementation) but certainly more elegant, solution.
function err_handler($errno, $errstr) {
// Ignore or log error here
}
set_error_handler('err_handler');
This way, the error message will not display, unless you explicitly echo it. Note, though, when using a custom error handler error_get_last will return NULL.
You can rewrite any system call function with a class like this:
file: system.php
namespace abc;
class System {
const CAN_NOT_MAKE_DIRECTORY = 1;
static public function makeDirectory($path) {
$cmd = "mkdir " . $path;
$output = \shell_exec($cmd . " 2>&1"); // system call
if ($output != "") {
throw new \Exception($output, System::CAN_NOT_MAKE_DIRECTORY);
}
return(\TRUE);
}
}
Then you can call the method and intercept the exception:
file: index.php
namespace abc;
require 'system.php';
try {
System::makeDirectory($directoryName);
} catch (\Exception $e) {
throw new \Exception($e->getMessage(), System::CAN_NOT_MAKE_DIRECTORY);
}
Now you can treat all the system errors with the try {...} catch(...) {...} finally {...} normally.

Categories