I just implemented a custom error with trigger_error() , but the problem is that the line that triggers trigger_error() is shown as a violation line in the call stack trace, not the calling line.
<?php trait ClassProtection { public function __get($name) { $class_name = get_called_class(); trigger_error("Public property {$class_name}::\${$name} does not exist", E_USER_ERROR); } public function __set($name, $value) { $class_name = get_called_class(); trigger_error("Public property {$class_name}::\${$name} does not exist and automatic creation has been disabled", E_USER_ERROR); } } class SomeClass { use ClassProtection; public $foo = 1; protected $bar = 2; private $baz = 3; } $sc = new SomeClass;
When reading a line //use ClassProtection; she produces the following:
C:\>php test_class_protection.php int(1) PHP Fatal error: Cannot access protected property SomeClass::$bar in C:\test_class_protection.php on line 28 PHP Stack trace: PHP 1. {main}() C:\test_class_protection.php:0 Fatal error: Cannot access protected property SomeClass::$bar in C:\test_class_protection.php on line 28 Call Stack: 0.0000 127344 1. {main}() C:\test_class_protection.php:0
If the string use ClassProtection; uncommented, it produces the following:
C:\>php test_class_protection.php int(1) PHP Fatal error: Public property SomeClass::$bar does not exist in C:\test_class_protection.php on line 5 PHP Stack trace: PHP 1. {main}() C:\test_class_protection.php:0 PHP 2. SomeClass->__get($name = 'bar') C:\test_class_protection.php:28 PHP 3. trigger_error('Public property SomeClass::$bar does not exist', 256) C:\test_class_protection.php:5 Fatal error: Public property SomeClass::$bar does not exist in C:\test_class_protection.php on line 5 Call Stack: 0.0000 127648 1. {main}() C:\test_class_protection.php:0 0.0000 128904 2. SomeClass->__get(string(3)) C:\test_class_protection.php:28 0.0000 129128 3. trigger_error(string(46), long) C:\test_class_protection.php:5
Note that there are two additional lines that are not useful and actually distract them when debugging. I want the second error to look like the first, except with the message configured.
As far as I remember, when I was working with Perl, it had some kind of trusted code mechanism, which prevented code marked as reliable from appearing on the stack. Is there a way in PHP to hide the last one or two calls in the call stack trace without rewriting the entire error handling procedure so that it looks like a standard PHP error occurred on the correct line?
Ideally, I would like to get a copy of the stack trace, modify it a bit, and return it to the standard PHP error handler.