2017-01-12 18 views
6

Vì vậy, tôi đã đọc về các ngoại lệ ngày hôm nay trên hướng dẫn sử dụng PHP trực tuyến, và nhận ra tôi vẫn chưa hiểu mục đích hoặc sự cần thiết thực sự của từ khóa cuối cùng. Tôi đã đọc một số bài viết ở đây, vì vậy câu hỏi của tôi hơi khác một chút.Làm thế nào keywod 'cuối cùng' có nghĩa là được sử dụng trong PHP

tôi hiểu rằng chúng tôi có thể sử dụng cuối cùng theo cách này:

function hi(){ 
    return 'Hi'; 
} 


try { 
    throw new LogicException("Throw logic \n"); 
} catch (InvalidArgumentException $e) { 
    echo $e->getMessage(); 
} 

echo hi(); 

đầu ra:

Fatal error: Uncaught LogicException: Throw Logic in C:\Users\...a.php:167 
Stack trace: 
#0 {main} 
    thrown in C:\Users\...a.php on line 167 

Vì vậy, trong trường hợp này các chức năng hi(); không được thực hiện và vì một lý do chính đáng. Tôi hiểu nếu ngoại lệ không được xử lý thông dịch viên php sẽ tạm dừng tập lệnh. tốt. Cho đến nay từ những gì tôi đọc, cuối cùng cho phép chúng ta thực thi hàm hi(); ngay cả khi ngoại lệ không được xử lý (mặc dù tôi không biết tại sao)

Vì vậy, điều này tôi hiểu.

try { 
    throw new LogicException("Throw logic \n"); 
} catch (InvalidArgumentException $e) { 
    echo $e->getMessage(); 
}finally{ 
    echo hi(); 
} 

đầu ra:

Hi 
Fatal error: Uncaught LogicException: Throw Logic in C:\Users\...a.php:167 
Stack trace: 
#0 {main} 
    thrown in C:\Users\...a.php on line 167 

này trên nên các lỗi ngoại lệ cũng như 'hi' thông điệp từ chức năng, thậm chí những người tôi không biết bất kỳ việc sử dụng cho việc này. Nhưng những gì tôi không nhấn mạnh điều này, ngay cả khi chúng tôi bắt các LogicException với bắt (LogicException $e) và không có trường hợp ngoại lệ được ném vẫn còn chúng tôi sẽ thấy chức năng đang được thực hiện, và chúng tôi sẽ thấy thông báo 'hi'. như trong ví dụ này

try { 
    throw new LogicException("Throw logic \n"); 
} catch (LogicException $e) { 
    echo $e->getMessage(); 
}finally{ 
    echo hi(); 
} 

đầu ra

// Throw logic 
// Hi 

Vì vậy, chúng tôi vẫn thấy chức năng hi() thực hiện mặc dù chúng tôi không có trường hợp ngoại lệ của router. Tại sao và việc sử dụng cho điều này là gì? Tôi nghĩ rằng khối cuối cùng đã được sử dụng như một phương sách cuối cùng trong trường hợp ngoại lệ đã không bị bắt, ngay cả khi đó không phải là trường hợp thì tại sao nó được sử dụng để chạy nó?

+0

Điều gì Bạn đang sử dụng phiên bản PHP nào? Chức năng True 'final' không được thêm vào cho đến khi PHP 5.5. –

+0

@AlecGordon php 7.0.1 –

+0

Ồ, thật lạ lùng. Theo [phân tích này] (https://adayinthelifeof.nl/2013/02/12/php5-5-trycatchfinally/) khối cuối cùng nên được in trước khi ngoại lệ không bị bắt. –

Trả lời

2

Khối cuối cùng sẽ được sử dụng khi bạn muốn thực thi mã nhất định bất kể ngoại lệ có bị ném hay không.

Một trong những cách sử dụng phổ biến hơn mà tôi thấy là đóng kết nối cơ sở dữ liệu - bạn muốn điều này xảy ra mỗi lần (có hoặc không có ngoại lệ), do đó bạn không kết thúc với một kết nối đang treo. kết nối mới.

Xem xét việc này pseudo-code:

try { 
    $database->execute($sql); 
} catch (Exception $exception) { 
    $logger->log($exception->getMessage()); 
    throw $exception; 
} finally { 
    $database->close(); 
} 
+1

Tôi hiểu nó bây giờ, nhưng các trường hợp sử dụng có vẻ rất hiếm. Trong ví dụ của bạn, bạn vẫn có thể đóng cơ sở dữ liệu trước khi 'ném' statment, và nó sẽ đạt được điều tương tự. –

+2

@mvrht: Tất nhiên bạn có thể đóng kết nối DB trước khi 'throw'statement _without_ sử dụng' final', nhưng vấn đề là trong trường hợp đó: Thứ nhất, có thể bạn không bắt _every_ ngoại lệ mà chỉ là một kiểu nhất định, sau đó bạn không đạt được lệnh gọi 'close()' cho các ngoại lệ khác. Thứ hai, ngay cả khi bạn bắt mọi ngoại lệ, thì bạn cần một dòng mã trùng lặp ở đâu đó (ở cuối 'try'block hoặc sau khối' catch') để gọi 'close()'. Đặt cuộc gọi đó trong khối 'cuối cùng', bạn phải viết nó chỉ một lần và nó được thực hiện trong mọi trường hợp (nếu ngoại lệ xảy ra hay không, nếu nó bị bắt hay không). – dwytrykus

0

Cuối cùng phải chứa bất kỳ mã nào cần được thực thi bất kể có ngoại lệ hay không.

Nếu không có cuối cùng:

try { 
    $handle = fopen("file.txt"); 
    //Do stuff 
    fclose($handle); 
    return something; 
} catch (Exception $e) { 
    // Log 
    if (isset($handle) && $handle !== false) { 
     fclose($handle); 
    }  
} 

Với cuối cùng:

try { 
    $handle = fopen("file.txt"); 
    return something; 
} catch (Exception $e) { 
    // Log 
} finally { 
    if (isset($handle) && $handle !== false) { 
     fclose($handle); 
    }  
} 

Cung cấp một chút decluttering trong trường hợp mà bạn cần để giải phóng một nguồn lực sau một chức năng đã trở lại.

này trở nên hữu ích hơn trong một trường hợp như sau:

try { 
    $handle = fopen("file.txt"); 
    if (case1) { return result1; } 
    if (case2) { return result2; } 
    if (case3) { return result3; } 
    if (case4) { return result4; } 

} finally { 
    if (isset($handle) && $handle !== false) { 
      fclose($handle); 
     }  
} 

Trong trường hợp này bạn có thể giảm tất cả các yêu cầu fclose cuộc gọi trước khi mỗi người trở về một fclose cuộc gọi duy nhất mà sẽ được thực hiện ngay trước khi phương pháp này trả về nhưng sau bất kỳ mã nào khác.

1
try { 
    throw new LogicException("Throw logic \n"); -> LogicException thrown 
} catch (InvalidArgumentException $e) { -> LogicException not catched 
    echo $e->getMessage(); 
}finally{ 
    echo hi(); -> code executed. "Hi" printed out 
} 

LogicException is here -> Fatal error 

như vậy trong trường hợp này:

try { 
    throw new LogicException("Throw logic \n"); -> LogicException thrown 
} catch (InvalidArgumentException $e) { -> LogicException not catched 
    echo $e->getMessage(); 
}finally{ 
    echo hi(); -> code executed 
    die(); 
} 

không lỗi nghiêm trọng sẽ được nâng lên, vì tuyên bố chết và sự thay đổi cuối cùng:

try { 
    throw new LogicException("Throw logic \n"); -> LogicException thrown 
} catch (InvalidArgumentException $e) { -> LogicException not catched 
    echo $e->getMessage(); 
} catch (LogicException $e) { -> LogicException catched 
    echo $e->getMessage(); 
}finally{ 
    echo hi(); -> code executed 
} 
Các vấn đề liên quan