2009-11-27 39 views
5

Nếu bạn sử dụng custom error handler trong PHP, bạn có thể thấy ngữ cảnh của một lỗi (giá trị của tất cả các biến tại vị trí xảy ra). Có cách nào để làm điều này cho trường hợp ngoại lệ? Tôi có nghĩa là nhận được bối cảnh, không phải thiết lập một xử lý ngoại lệ.Nhận bối cảnh ngoại lệ trong PHP

Trả lời

8

Bạn có thể đính kèm các ngữ cảnh để ngoại trừ của bạn bằng tay. Tôi đã không bao giờ thử nó, nhưng nó sẽ là thú vị để tạo ra một ngoại lệ tùy chỉnh mà trong constructor gọi và tiết kiệm get_defined_vars() để truy xuất sau này.
Đây sẽ là một ngoại lệ nặng :-)

bằng chứng của khái niệm:

class MyException extends Exception() { 
    protected $throwState; 

    function __construct() { 
     $this->throwState = get_defined_vars(); 
     parent::__construct(); 
    } 

    function getState() { 
     return $this->throwState; 
    } 
} 

thậm chí tốt hơn:

class MyException extends Exception implements IStatefullException() { 
    protected $throwState; 

    function __construct() { 
     $this->throwState = get_defined_vars(); 
     parent::__construct(); 
    } 

    function getState() { 
     return $this->throwState; 
    } 

    function setState($state) { 
     $this->throwState = $state; 
     return $this; 
    } 
} 

interface IStatefullException { function getState(); 
     function setState(array $state); } 


$exception = new MyException(); 
throw $exception->setState(get_defined_vars()); 
+1

Hmm, nhưng get_defined_vars ở đây sẽ không bao gồm các biến cục bộ từ mã xây dựng ngoại lệ, phải không? –

+0

Không, nếu chúng không hiển thị với 'Ngoại lệ '. Để khắc phục điều này, tôi khuyên bạn nên thêm một phương thức 'setState (array $ state)' và cung cấp 'get_defined_vars' khi bạn ném ngoại lệ. Tôi đã thay đổi mã cho phù hợp. –

+0

Cách chính xác để làm điều đó là như Andrew đã đề cập dưới đây. * Lưu ý: * Ngoại lệ không nên thay đổi! Một khi bạn ném nó, nó không nên thay đổi ... do đó tại sao 'setState()' là một ý tưởng tồi;) ** PS: ** đây là cách nó được thực hiện [trong Symfony] (https://github.com/ ladybirdweb/agorainvoicing/blob/master/vendor/symfony/debug/Exception/ContextErrorException.php) (tuyên bố từ chối trách nhiệm: tôi đã viết nó) – Christian

-2

Chức năng tương đương để xử lý eceptions là:
set_exception_handler()

Một chức năng rất hữu ích là:
debug_backtrace()

+0

Có, nhưng đó không phải là câu hỏi của tôi. Tôi cần lấy bối cảnh từ một ngoại lệ mà tôi đã bị bắt. Cảm ơn thời gian của bạn mặc dù –

+1

Theo mặc định PHP ngoại lệ không chứa thông tin đó, và do thời gian bạn đã bắt được ngoại lệ, thông tin về vars địa phương vv mà bạn muốn đã bị phá hủy vì khung stack gốc đã được xuất hiện . Nếu bạn không có quyền kiểm soát bối cảnh mà trường hợp ngoại lệ đã được ném để bạn có thể thêm ngữ cảnh ở đó, thì không có cách nào để bạn có được ngữ cảnh đó. –

+0

Có, nhưng điều này không trả lời câu hỏi được hỏi. – Octavian

1

Exceptions trong PHP:

http://www.php.net/manual/en/language.exceptions.extending.php

Các phương thức của lớp Ngoại lệ cơ bản:

final public function getMessage();  // message of exception 
final public function getCode();   // code of exception 
final public function getFile();   // source filename 
final public function getLine();   // source line 
final public function getTrace();   // an array of the backtrace() 
final public function getPrevious();  // previous exception 
final public function getTraceAsString(); // formatted string of trace 

Vì vậy, đây là những gì bạn phải làm việc nếu bạn gặp ngoại lệ cơ bản. Nếu bạn không có quyền kiểm soát mã tạo ra ngoại lệ thì không có nhiều việc phải làm khi nhận thêm bất kỳ bối cảnh nào vì bối cảnh mà nó bị ném đi mất khi bạn bắt được nó. Nếu bạn đang tạo ra ngoại lệ cho mình thì bạn có thể đính kèm ngữ cảnh này vào ngoại lệ trước khi nó được ném ra.

2

Không thể bạn cũng làm:

class ContextException extends Exception { 

    public $context; 

    public function __construct($message = null, $code = 0, Exception $previous = null, $context=null) { 
     parent::__construct($message, $code, $previous); 
     $this->context = $context; 
    } 

    public function getContext() { 
     return $this->context; 
    } 
} 

Điều đó sẽ tránh sự cần thiết để nhanh chóng các ngoại lệ và sau đó ném nó.

Các vấn đề liên quan