i have this:
i have An HTTACCESS file with directive to prepend a file for config and handle error: (it is mandatory: According to the documentation, this file must be attached before any other php script is executed in order to obtain errors: such as E_PARSE.)
php_value auto_prepend_file "./server/conferror.php"
the content of conferror.php:
<?php
declare(strict_types=1);
ini_set('session.gc_maxlifetime', '0');
ini_set('session.use_only_cookies', '1');
ini_set('session.cookie_httponly', '1');
ini_set('allow_url_fopen', '1');
ini_set('allow_url_include', '1');
ini_set('error_reporting', '1');
ini_set('display_errors', '0');
error_reporting(E_ALL);
set_error_handler("ErrorHandler");
register_shutdown_function("ShutdownHandler");
function ErrorHandler($error_level, $error_message, $error_file, $error_line, $error_context) {
$ErrorHandler = "<b>File:</b> " . $error_file . '<br>' .
"<b>Line :</b> " . $error_line . '<br>' .
"<b>Desc:</b> <br>" . $error_message . '<br>';
echo $ErrorHandler;
exit;
}
function ShutdownHandler() {
$CheckError = error_get_last();
if ($CheckError != null) {
$ErrorHandler = "<b>File:</b> " . $CheckError['file'] . '<br>' .
"<b>Line :</b> " . $CheckError['line'] . '<br>' .
"<b>Desc:</b> <br>" . $CheckError['message'] . '<br>';
echo $ErrorHandler;
exit;
}
}
?>
in my index.php i have this to start work the aplication:
<?php
require_once 'class.Main.php';
$WebAPP = new CORE();
$WebAPP->Main();
?>
in Main file i have a test, this code to unset a Static Object and Test Erros Handlers:
<?php
class CORE {
public static $ObjClass;
public function __construct() {
self::$ObjClass['data']='data';
}
public function __destruct() {
unset(CORE::$ObjClass);
}
public function Main() {
#not Test on this.
}
}
?>
I have 3 questions:
- Why Event handler does not capture the following error?
Fatal error: Uncaught Error: Attempt to unset static property CORE::$ObjClass in C:\xampp\htdocs\dev\t2\class.Main.php:8 Stack trace: #0 [internal function]: CORE->__destruct() #1 {main} thrown in C:\xampp\htdocs\dev\t2\class.Main.php on line 8
Second test:
This code:
<?php
class CORE {
public function __construct() {
}
public function __destruct() {
prom();
}
public function Main() {
#not Test on this.
}
}
?>
Generate this error:
Fatal error: Uncaught Error: Call to undefined function prom() in C:\xampp\htdocs\dev\t2\class.Main.php:6 Stack trace: #0 [internal function]: CORE->__destruct() #1 {main} thrown in C:\xampp\htdocs\dev\t2\class.Main.php on line 6
Update:
after much test i see that the error handler work fine with errors in declared function; but this not work in __construct
or__destruct
function.
- Why i cant unset static property CORE::$ObjClass or self::$ObjClass?
Good question. I don't see anything in the official documentation of unset()
or static properties that mentions this. But obviously you can't.
- What is the right way to do it with static property?
You could just set it to NULL
or an empty array.
- Why Event handler does not capture the following error?
The documentation says:
The following error types cannot be handled with a user defined function: E_ERROR
, E_PARSE
, E_CORE_ERROR
, E_CORE_WARNING
, E_COMPILE_ERROR
, E_COMPILE_WARNING
, and most of E_STRICT
raised in the file where set_error_handler()
is called.
This error is presumably one of these types. I'm not sure how to tell specifically what its type is.
The shutdown function is being called, but for some reason error_get_last()
is returning NULL
rather than the information about this error.
After doing a lot of searching in the documentation and online.
it is not clear why the error handlers do not work correctly in the __construct
or __desctruct
; but as a remote idea I am assuming that these two functions are verified even before interpreting the HTTACCESS
files or that even though the file is executed the directives: php_value auto_prepend_file
is being executed after the two functions __construct
and __desctruct
are verified, this severely disrupts how handle errors and can lead to implement solutions not as comfortable as the following.
As a first point I had to implement another set that I had not read before or found, in the research I found it:
set_exception_handler ("ExeptionHandler");
and I imagine that I will have to implement others to the extent.
as a second point for this personal development: you should go from using any Method of these __construc
and __destruct
, and migrate to nesting everything in the declared methods.
Then the script and the structure are as follows:
HTTACCESS Files (Same):
php_value auto_prepend_file "./server/conferror.php"
conferror.php(Update with new set):
<?php
declare(strict_types=1);
ini_set('session.gc_maxlifetime', '0');
ini_set('session.use_only_cookies', '1');
ini_set('session.cookie_httponly', '1');
ini_set('allow_url_fopen', '1');
ini_set('allow_url_include', '1');
ini_set('error_reporting', '1');
ini_set('display_errors', '0');
error_reporting(E_ALL);
register_shutdown_function("ShutdownHandler");
set_error_handler("ErrorHandler");
set_exception_handler("ExeptionHandler");
function ShutdownHandler() {
$CheckError = error_get_last();
if ($CheckError != null) {
$ErrorHandler = "<b>File:</b> " . $CheckError['file'] . '<br>' .
"<b>Line:</b> " . $CheckError['line'] . '<br>' .
"<b>Desc:</b> <br>" . $CheckError['message'] . '<br>';
echo $ErrorHandler;
}
}
function ErrorHandler($error_level, $error_message, $error_file, $error_line, $error_context) {
$ErrorHandler = "<b>File:</b> " . $error_file . '<br>' .
"<b>Line:</b> " . $error_line . '<br>' .
"<b>Desc:</b> <br>" . $error_message . '<br>';
echo $ErrorHandler;
}
function ExeptionHandler($e) {
$ErrorHandler = "<b>File:</b> " . $e->getFile() . '<br>' .
"<b>Line:</b> " . $e->getLine() . '<br>' .
"<b>Desc:</b> <br>" . $e->getMessage() . '<br>';
echo $ErrorHandler;
}
?>
index.php (same not changed):
<?php
require_once 'class.Main.php';
$WebAPP = new CORE();
$WebAPP->Main();
?>
Script Main to Test (Update: remove __construct
and __destruct
from programing structure):
<?php
class CORE {
public static $ObjClass;
public function Main() {
#not Test on this.
self::$ObjClass['data'] = 'data';
unset(CORE::$ObjClass);
}
}?>
For the moment is all that can make with this. i will update it if i find new information in the future.