2012-01-12 41 views
6

Tôi biết, rằng theo định nghĩa của nó, một ngoại lệ chết người được cho là sẽ giết thực thi, và không nên bị đàn áp, nhưng đây là vấn đề.Bắt ngoại lệ chết người và tiếp tục

Tôi đang chạy tập lệnh để phân tích, phân tích cú pháp và lưu trữ trong DB khoảng 10.000 trang. Quá trình này mất một vài giờ và trong một số ít trường hợp (1 trong 1000) một trang không phân tích cú pháp và ném một ngoại lệ gây tử vong.

Hiện nay, tôi đang làm điều này:

for ($i=0;$i<$count;$i++) 
     { 
      $classObject = $classObjects[$i];   

      echo $i . " : " . memory_get_usage(true) . "\n"; 

      $classDOM = $scraper->scrapeClassInfo($classObject,$termMap,$subjectMap);   
      $class = $parser->parseClassInfo($classDOM);      
      $dbmanager->storeClassInfo($class);   

      unset($classDOM,$class,$classObject);   
     }   

Tôi có thể làm điều gì đó như

for ($i=0;$i<$count;$i++) 
{ 
    $classObject = $classObjects[$i];    
    echo $i . " : " . memory_get_usage(true) . "\n"; 

    try 
    { 
     $classDOM = $scraper->scrapeClassInfo($classObject,$termMap,$subjectMap);   
     $class = $parser->parseClassInfo($classDOM);     
     $dbmanager->storeClassInfo($class);   
     unset($classDOM,$class,$classObject);   
    } 
    catch (Exception $e) 
    { 
     //log the error here 
     continue; 
    } 
} 

Đoạn mã trên không làm việc cho fatal exceptions.

Có thể thực hiện một việc như sau: Nếu tôi đã chuyển vòng lặp chính vào một phương thức, sau đó gọi phương thức từ register_shutdown_function?

Như thế này:

function do($start) 
{ 
    for($i=$start;$i<$count;$i++) 
    { 
     //do stuff here 
    } 
} 

register_shutdown_function('shutdown'); 

function shutdown() 
{ 
    do(); 
} 

Đây là thông điệp mà là đầu ra khi thực hiện ngừng:

Fatal error: Call to a member function find() on a non-object in ... 

Tôi hy vọng thông điệp trên này khi một trang không được phân tích-thể bằng phương pháp tôi đang sử dụng. Tôi tốt với chỉ bỏ qua trang đó và chuyển sang vòng lặp tiếp theo của vòng lặp.

+3

'Ngoại lệ chết người' là gì? Làm thế nào là 'bắt của bạn (ngoại lệ $ e)' không hoạt động? – cspray

+1

Thật vậy ..... Có ai đó ném thứ gì đó không mở rộng 'Ngoại lệ' không? – Wrikken

+0

... trong trường hợp nào, bạn không thể chỉ bắt '} ($ e) {'? – DaveRandom

Trả lời

10

Lỗi nghiêm trọng gây tử vong và chấm dứt thực thi. Không có cách nào xung quanh việc này nếu xảy ra lỗi nghiêm trọng. Tuy nhiên, lỗi của bạn:

Fatal error: Call to a member function find() on a non-object in ...

hoàn toàn có thể ngăn ngừa được. Chỉ cần thêm một dấu kiểm để đảm bảo rằng bạn có một phiên bản của đối tượng chính xác và nếu không, hãy xử lý lỗi:

if ($foo instanceof SomeObject) { 
    $foo->find(...); 
} else { 
    // something went wrong 
} 
+0

Vâng, điều này có vẻ là cách tốt nhất để xử lý nó thay vì để cho nó leo thang đến một lỗi nghiêm trọng – xbonez

+0

@mfonda làm thế nào để tìm loại đó là gì? –

1

Dường như với tôi như cách duy nhất có thể để "bắt" một lỗi faltal là với việc đăng ký một chức năng tắt máy. Hãy nhớ thêm tất cả (hoặc có thể nhóm) truy vấn vào các giao dịch và có thể cuộn chúng lại nếu có điều gì đó không thành công, chỉ để đảm bảo tính nhất quán.

+1

Trên một lỗi nghiêm trọng, tôi không tìm cách thoát ra một cách duyên dáng (dọn dẹp, giao dịch rollback và sau đó thoát). Tôi đang tìm cách đăng nhập lỗi và tiếp tục. Điều đó có thể không? Tôi cho rằng có khả năng là không. – xbonez

+1

Kiểm tra liên kết này http://www.php.net/manual/en/function.register-shutdown-function.php, kiểm tra các thư mà chúng đã tạo, một số có liên quan đến vấn đề của bạn. Nhưng bạn nên cố gắng tránh các lỗi nhiều nhất có thể trong mã của bạn – guiman

6

Trước tiên, có sự khác biệt rõ ràng giữa exceptionserrors. Những gì bạn gặp phải là lỗi , không phải ngoại lệ. Dựa trên thông điệp của bạn và mã bạn đăng vấn đề là với một cái gì đó bạn đã không đưa vào câu hỏi của bạn. Biến số nào bạn đang cố gắng gọi find()? Vâng, biến đó không phải là một đối tượng. Không có cách nào để bẫy lỗi nghiêm trọng và bỏ qua nó, bạn phải đi tìm nơi bạn đang gọi find() trên một đối tượng không phải và sửa chữa nó.

+0

Thư viện trình phân tích cú pháp dom html Tôi đang sử dụng trả về một đối tượng (cấu trúc DOM của trang) và tôi sử dụng 'object-> find()' để tìm một số yếu tố. Khi một trang không phân tích cú pháp, nó không trả về đối tượng và do đó 'object-> find()' ném một lỗi nghiêm trọng. Tôi cho rằng tôi có thể đặt một kiểm tra 'is_object()' trước khi gọi 'find()' – xbonez

+1

@xbonez Đó sẽ là câu trả lời cho vấn đề của bạn, vì trình phân tích cú pháp DOM thất bại sẽ không gây ra lỗi nghiêm trọng. Bạn cũng có thể sử dụng toán tử 'instanceof' như được gợi ý bởi @mfonda bên dưới. – DaveRandom

+2

@xbonez Đó là một tùy chọn. Hoặc bạn có thể triển khai mẫu thiết kế ['NullObject'] (http://sourcemaking.com/design_patterns/null_object). Về cơ bản bạn thiết lập một thực hiện khi bạn gọi '$ object-> find()' nó trả về một đối tượng rỗng mà bạn vẫn có thể gọi các phương thức trên. Điều này sẽ đảm bảo rằng bạn luôn có một đối tượng để gọi một phương thức và bạn không phải thực hiện các kiểm tra đối tượng đó. – cspray

1

Tôi đã gặp vấn đề tương tự như vậy và tôi thấy rằng sử dụng lệnh gọi is_object() trước khi cuộc gọi find() cho phép bạn tránh được lỗi nghiêm trọng.

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