我刚刚使用trigger_error()
实现了自定义错误,但问题是调用trigger_error()
的行在调用堆栈跟踪中显示为违规行,而不是调用行。
<?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;
// Try to access existing public property: should work
var_dump($sc->foo);
$sc->foo = 11;
// Try to access existing protected property: should not work - fatal error
var_dump($sc->bar);
$sc->bar = 12;
// Try to access existing private property: should not work - fatal error
var_dump($sc->baz);
$sc->baz = 13;
// Try to create new public property: should not work - fatal error
$sc->qux = 14;
var_dump($sc->qux);
注释行//use ClassProtection;
后,会产生以下内容:
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
取消注释行use ClassProtection;
后,会产生以下内容:
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
请注意,在调试时,有两个额外的行没有用,实际上会分散注意力。我希望第二个错误看起来像第一个,除了自定义的消息。
我似乎记得从我以前使用Perl时它有一些可靠的代码机制,阻止标记为受信任的代码出现在堆栈跟踪中。在PHP中是否有任何方法可以隐藏调用堆栈跟踪中的最后一个或两个调用而不重写整个error handling例程,以便它看起来像是在正确的行上发生标准PHP错误?
理想情况下,我想获得堆栈跟踪的副本,稍微修改它并将其返回给PHP的标准错误处理程序。