2011-12-14 30 views
7

odbc_errormsg không báo cáo các thông báo lỗi từ odbc_execute cách thức được yêu cầu. Nó chỉ ném một cảnh báo. Vì vậy, tôi đã buộc phải viết một hack để phân tích cú pháp thông báo lỗi thông qua error_get_last.error_get_last() và trình xử lý lỗi tùy chỉnh

Tôi đang sử dụng set_error_handlererror_get_last lợi nhuận NULL trừ khi tôi hoặc là:

  1. vô hiệu hóa xử lý lỗi của tôi,

  2. hoặc làm cho nó trở FALSE.

Tôi cho rằng điều này là do trình xử lý lỗi dựng sẵn của PHP xử lý việc lưu trữ chi tiết lỗi ở đâu đó để chúng có thể được truy xuất sau này.

Có cách nào để mô phỏng hành vi như vậy trong trình xử lý lỗi tùy chỉnh của tôi để error_get_last() có thể được sử dụng bình thường không?

Xin lưu ý Tôi đã biết một số cách để truy xuất thông tin lỗi bất kỳ lúc nào. Câu hỏi của tôi là làm thế nào để làm cho error_get_last có thể sử dụng được.


Cập nhật: Tôi nghĩ mình tốt hơn muốn đăng một số mã.

PHP có error_get_last(), cho phép thực hiện điều này:

@fopen('xxx'); 
var_dump(error_get_last()); 

... và có được điều này:

array(4) { 
    ["type"]=> 
    int(2) 
    ["message"]=> 
    string(46) "fopen() expects at least 2 parameters, 1 given" 
    ["file"]=> 
    string(69) "C:\Documents and Settings\ALVARO.GONZALEZ\Mis documentos\tmp\test.php" 
    ["line"]=> 
    int(3) 
} 

này phá vỡ nếu bạn thay thế xử lý lỗi BUILTIN:

function custom_error_handler($errno, $errstr, $errfile, $errline){ 
    $ignore = ($errno & error_reporting()) == 0; 
    if(!$ignore){ 
     echo "[Error happened: $errstr]\n"; 
    } 
    return TRUE; 
} 
set_error_handler('custom_error_handler'); 

@fopen('xxx'); 
var_dump(error_get_last()); // NULL 

Nếu bạn giữ cả hai trình xử lý lỗi ...

function custom_error_handler($errno, $errstr, $errfile, $errline){ 
    $ignore = ($errno & error_reporting()) == 0; 
    if(!$ignore){ 
     echo "[Error happened: $errstr]\n"; 
    } 
    return FALSE; 
} 
set_error_handler('custom_error_handler'); 

error_reporting(E_ALL); 
echo $foo; 

... bạn sẽ có được tác dụng phụ:

[Error happened: Undefined variable: foo] 

Notice: Undefined variable: foo in C:\Documents and Settings\ALVARO.GONZALEZ\Mis documentos\tmp\test.php on line 15 

Call Stack: 
    0.0004  329720 1. {main}() C:\Documents and Settings\ALVARO.GONZALEZ\Mis documentos\tmp\test.php:0 

... thay vì chỉ:

[Error happened: Undefined variable: foo] 

Tôi muốn xử lý lỗi tùy chỉnh của tôi để giao tiếp đúng với error_get_last. Tôi muốn error_get_last hoạt động tốt.

+0

Bạn có chấp nhận sử dụng chức năng khác (do người dùng xác định) không? Bởi vì nếu bạn muốn, bạn chỉ có thể lưu trữ lỗi cuối cùng trong một var toàn cục, và có một hàm chỉ trả về $ GLOBALS ['varname']; ' – DaveRandom

+0

Trả về 'false' không được chấp nhận? Nếu vậy, tại sao? – Jon

+0

Ngoài ra, bạn đã thử gán giá trị cho ['$ php_errormsg'] (http://uk.php.net/manual/en/reserved.variables.phperrormsg.php) chưa? Tôi không có ý tưởng nếu điều này sẽ đạt được (hoặc thậm chí ảnh hưởng) bất cứ điều gì, nhưng nó có thể là giá trị một thử ... – DaveRandom

Trả lời

5

Phải, đây là giải pháp kỳ lạ, nhưng tôi nghĩ rằng nó sẽ phù hợp với mục đích của bạn.

Sau một chút chơi xung quanh, tôi đã phát hiện ra rằng đây:

function my_error_handler ($errno, $errstr, $errfile = '', $errline = 0, $errcontext = array()) { 

    // Handle the error here 

    @trigger_error($errstr); 
    return TRUE; 

} 

// Just to make sure PHP is not outputting anything 
error_reporting(-1); 
ini_set('display_errors',1); 

set_error_handler('my_error_handler'); 

// An E_USR error... 
trigger_error('Some error'); 
var_dump(error_get_last()); 

// ...and a native one 
$key = count(); 
var_dump(error_get_last()); 

Kết quả trong này:

array(4) { 
    ["type"]=> 
    int(1024) 
    ["message"]=> 
    string(10) "Some error" 
    ["file"]=> 
    string(69) "C:\Program Files\Apache Software Foundation\Apache2.2\htdocs\test.php" 
    ["line"]=> 
    int(7) 
} 
array(4) { 
    ["type"]=> 
    int(1024) 
    ["message"]=> 
    string(45) "count() expects at least 1 parameter, 0 given" 
    ["file"]=> 
    string(69) "C:\Program Files\Apache Software Foundation\Apache2.2\htdocs\test.php" 
    ["line"]=> 
    int(7) 
} 

Calling @trigger_error() từ bên trong xử lý lỗi của bạn, và không trở về FALSE, gây error_get_last() để trả về một cái gì đó khác hơn là NULL, nhưng vì lỗi bị chặn với @, PHP không xuất ra bất cứ thứ gì. Dường như vì lợi ích của việc tránh một đệ quy vô hạn, gọi trigger_error() từ bên trong hàm xử lý lỗi đã đăng ký không gọi trình xử lý lỗi - hoạt động với lợi thế của chúng ta ở đây.

Rõ ràng, mã lỗi đã được sửa đổi, nhưng bạn có thể chuyển đổi mã thành mã E_USR_* liên quan nếu bạn cần - nhưng tôi nghi ngờ điều bạn thực sự muốn là giá trị chuỗi, phương pháp này sẽ cho phép bạn nhận được. Bạn có, không may, cũng bị mất số dòng và thông tin tệp - mặc dù bạn có thể lấy lại bằng cách thực hiện một thứ gì đó liên quan đến dấu vết ngăn xếp bên trong trình xử lý lỗi hoặc ít nhất bao gồm nó trong chuỗi từ các đối số được truyền.

Đây là một bản hack khủng khiếp, kinh khủng, khủng khiếp - nhưng vì không có cách nào được chính thức xử phạt để thực hiện việc này, một bản hack là bản chất những gì bạn đang yêu cầu.

+0

Dí dỏm ... Tôi cần nghiên cứu cẩn thận :) –

+0

@ ÁlvaroG.Vicario, dí dỏm như http: //ioccc.org ..... – Pacerier

0

Bạn có thể thay đổi trình xử lý lỗi tùy chỉnh của mình để trả về false, chỉ khi lỗi bị bỏ qua (@ -operator được sử dụng).

function custom_error_handler($errno, $errstr, $errfile, $errline){ 
    $ignore = ($errno & error_reporting()) == 0; 
    if ($ignore) { 
     return FALSE; 
    } 
    echo "[Error happened: $errstr]\n"; 
    return TRUE; 
} 
Các vấn đề liên quan