2009-07-17 49 views
9

Có cách nào để làm cho mã tiếp tục (không thoát) khi bạn gặp lỗi nghiêm trọng trong PHP không? Ví dụ, tôi nhận được một lỗi thời gian chờ nghiêm trọng và tôi muốn bất cứ khi nào nó xảy ra để bỏ qua nhiệm vụ này và tiếp tục với những người khác. Trong trường hợp này, tập lệnh thoát.Lỗi nghiêm trọng php

+0

Nếu bạn đang chạy một kịch bản PHP mà đòi nói hơn 2-4 giây để thực hiện, sau đó bạn đang làm điều gì đó sai trái. Sử dụng công nghệ khác hoặc thay đổi quy trình làm việc của bạn. –

+3

@Alec Thông minh Tôi không đồng ý với điều đó - công việc cron vv thường xuyên mất nhiều thời gian hơn một vài giây. Có lẽ nó sẽ chạy nhanh hơn trong C + +, nhưng sau đó bạn sẽ phải thuê một lập trình C++ ... – Greg

Trả lời

13

Có lỗi khi sử dụng bộ đệm đầu ra sẽ cho phép bạn ghi lại một số lỗi nghiêm trọng, nhưng không có cách nào để tiếp tục tập lệnh sau khi xảy ra lỗi nghiêm trọng - đó là điều khiến nó gây tử vong!

Nếu tập lệnh của bạn hết thời gian, bạn có thể sử dụng set_time_limit() để có thêm thời gian để thực thi.

1

Tùy thuộc vào loại lỗi chính xác. Bạn có thể bắt lỗi bằng cách tạo trình xử lý lỗi của riêng bạn. Xem tài liệu trên set_error_handler(), nhưng không phải tất cả các loại lỗi đều có thể bị phát hiện. Nhìn vào lỗi thời gian chờ bạn nhận được và xem loại đó là gì. Nếu đó là một trong các E_ERROR, E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR hoặc E_COMPILE_WARNING thì bạn không thể bắt nó bằng trình xử lý lỗi. Nếu đó là loại khác thì bạn có thể. Bắt nó với trình xử lý lỗi và chỉ cần trả về.

0

Có cách nào để giới hạn thời gian thực hiện của một hàm không phải tất cả tập lệnh không? Ví dụ:

function blabla() 
{ 
return "yes"; 
} 

để làm như vậy nếu không được thực hiện sau 25 giây để trả lại không;

+0

không, bạn không thể giới hạn thời gian thực hiện của một hàm. – Quamis

7

"Lỗi nghiêm trọng", như tên gọi của nó, là Tử vong: nó dừng việc thực thi tập lệnh/chương trình.

Nếu bạn đang sử dụng PHP để tạo trang web và gặp lỗi nghiêm trọng liên quan đến max_execution_time, theo mặc định, bằng 30 giây, bạn chắc chắn đang làm điều gì đó thực sự mất quá nhiều thời gian: người dùng sẽ không chờ đợi lâu để có được trang.

Nếu bạn đang sử dụng PHP để làm một số tính toán nặng, không phải trong một trang web (nhưng qua CLI, hoặc một cron, hoặc những thứ như thế), bạn có thể thiết lập một (lớn) giá trị cho max_execution_time. Bạn có hai cách để làm điều đó:

Đầu tiên là sửa đổi php.ini, để đặt giá trị này (nó đã có trong tệp; chỉ cần chỉnh sửa giá trị của thuộc tính). Vấn đề là nó sẽ sửa đổi nó cũng cho máy chủ web, đó là xấu (đây là một biện pháp an ninh, sau khi tất cả). Cách tốt hơn là tạo một bản sao của php.ini, được gọi là, ví dụ, phpcli.ini và sửa đổi tệp này. Sau đó, sử dụng nó khi gọi php:

php -c phpcli.ini myscript.php 

Điều này sẽ hoạt động tốt nếu bạn có nhiều thuộc tính cần thiết để thực hiện CLI. (Giống như memory_limit, mà thường phải được thiết lập để một giá trị cao hơn cho đợt kéo dài)

Một cách khác là để xác định một giá trị khác nhau cho max_execution_time khi bạn gọi php, như thế này:

php -d max_execution_time=60 myscript.php 

Điều này là tuyệt vời nếu bạn khởi động điều này thông qua crontab, ví dụ.

1

Nếu bạn có phiên bản PHP phù hợp (PHP = 5.2 cho error_get_last), bạn có thể thử kỹ thuật được mô tả here sử dụng register_shutdown_function và error_get_last.

Điều này sẽ không cho phép bạn "tiếp tục" khi bạn gặp lỗi nghiêm trọng, nhưng ít nhất nó cũng cho phép bạn ghi lại lỗi (và có thể gửi email cảnh báo) trước khi hiển thị trang lỗi tùy chỉnh cho người dùng.

Nó hoạt động một cái gì đó như thế này:

function fatalErrorHandler() 
{ 
    $lastError = error_get_last(); 
    if (isset($lastError["type"]) && $lastError["type"]==E_ERROR) { 
     // do something with the fatal error 
    } 
} 
... 
register_shutdown_function('fatalErrorHandler'); 


Một vài điểm:

  • bạn có thể sử dụng ob_clean() để xóa mọi nội dung được tạo ra trước khi lỗi nghiêm trọng.
  • đó là một ý tưởng không thực sự là thực sự để làm bất cứ điều gì chuyên sâu trong trình xử lý tắt máy, kỹ thuật này là về sự thất bại duyên dáng thay vì phục hồi.
  • bất cứ điều gì bạn làm, không cố đăng nhập lỗi vào cơ sở dữ liệu ... nếu đó là thời gian chờ của cơ sở dữ liệu gây ra lỗi nghiêm trọng thì sao?
  • vì một số lý do tôi gặp sự cố khi sử dụng kỹ thuật này để làm việc 100% thời gian khi phát triển trong Windows bằng WAMP.
0

Câu trả lời đơn giản nhất mà tôi có thể cung cấp cho bạn là chức năng này: http://php.net/manual/en/function.pcntl-fork.php

Cụ thể hơn, những gì bạn có thể làm là:

  • Fork một phần của quá trình này bạn nghĩ có thể hoặc có thể không gây ra lỗi nghiêm trọng (nghĩa là số lượng lớn mã của bạn)
  • Kịch bản dành cho tiến trình phải là một tập lệnh rất đơn giản.

Ví dụ này là một cái gì đó mà tôi sẽ làm gì với một hàng đợi công việc mà tôi có:

<?php 
// ... load stuff regarding the job queue 

while ($job = $queue->getJob()) { 
    $pid = pcntl_fork(); 
    switch ($pid) { 
     case -1: 
      echo "Fork failed"; 
      break; 
     case 0: 
      // do your stuff here 
      echo "Child finished working"; 
      break; 
     default: 
      echo "Waiting for child..."; 
      pcntl_wait($status); 
      // check the status using other pcntl* functions if you want 
      break; 
    } 
} 
Các vấn đề liên quan