Menu
Coddy logo textTech

Try, Catch, Finally

Coddy PHP 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨 — 91개 중 68번째.

이제 예외를 생성하고 던지는 방법을 알게 되었으므로, 그것들을 catch하는 방법을 배워야 합니다. try-catch-finally 구조를 사용하면 애플리케이션이 중단되도록 내버려 두는 대신 예외를 유연하게 처리할 수 있습니다.

예외를 발생시킬 수 있는 코드를 try 블록으로 감싸고, catch 블록에서 예외를 처리하세요:

<?php
class Calculator {
    public function divide(int $a, int $b): float {
        if ($b === 0) {
            throw new InvalidArgumentException("Cannot divide by zero");
        }
        return $a / $b;
    }
}

$calc = new Calculator();

try {
    echo $calc->divide(10, 0);
} catch (InvalidArgumentException $e) {
    echo "Error: " . $e->getMessage();
}

출력:

Error: Cannot divide by zero

여러 개의 catch 블록을 사용하여 다양한 예외 유형을 포착할 수 있습니다. PHP는 이를 순서대로 확인하므로, 더 구체적인 예외를 먼저 배치하십시오:

<?php
try {
    // 위험한 코드
} catch (InvalidArgumentException $e) {
    echo "Bad input: " . $e->getMessage();
} catch (Exception $e) {
    echo "Something went wrong: " . $e->getMessage();
}

finally 블록은 예외가 발생하거나 포착되었는지 여부에 관계없이 실행됩니다. 연결 닫기와 같은 정리 작업에 적합합니다:

<?php
try {
    echo "Attempting operation\n";
    throw new Exception("Failed");
} catch (Exception $e) {
    echo "Caught: " . $e->getMessage() . "\n";
} finally {
    echo "Cleanup complete";
}

출력:

Attempting operation
Caught: Failed
Cleanup complete

finally 블록은 try 또는 catch 블록 내에서 return 하더라도 실행되므로, 필수적인 정리 작업을 수행하는 데 신뢰할 수 있습니다.

challenge icon

챌린지

쉬움

에러를 우아하게 처리하면서 항상 정리가 수행되도록 보장하는 try-catch-finally의 작동 방식을 보여주는 파일 처리 시스템을 구축해 보겠습니다.

코드는 세 개의 파일로 구성됩니다:

  • FileException.phpException을 상속받는 사용자 정의 FileException 클래스를 생성합니다. 이는 시스템에서 파일 관련 에러를 나타냅니다.
  • FileProcessor.php — 파일 작업을 시뮬레이션하는 FileProcessor 클래스를 생성합니다. FileException 파일을 포함하세요. 클래스에는 다음이 포함되어야 합니다:
    • false로 초기화된 프라이빗 불리언 속성 $isOpen
    • $isOpentrue로 설정하고 "Opening: [filename]"을 출력하는 open(string $filename): void 메서드. 만약 파일 이름이 "invalid.txt"라면, "Cannot open file"이라는 메시지와 함께 FileException을 던집니다.
    • "Processing file..."을 출력하는 process(): void 메서드. 만약 $isOpenfalse라면, "File not open"이라는 메시지와 함께 RuntimeException을 던집니다.
    • $isOpenfalse로 설정하고 "File closed"를 출력하는 close(): void 메서드
    • 현재 상태를 반환하는 isOpen(): bool 메서드
  • main.php — FileProcessor 파일을 포함하세요. 하나의 입력으로 파일 이름을 받게 됩니다.

    FileProcessor를 생성하고 try-catch-finally 구조를 사용하여 다음을 수행합니다:

    • try 블록에서: 파일 이름으로 open()을 호출한 다음 process()를 호출합니다.
    • 먼저 FileException을 캐치하고 "File error: [message]"를 출력합니다.
    • RuntimeException을 캐치하고 "Runtime error: [message]"를 출력합니다.
    • finally 블록에서: isOpen()을 사용하여 파일이 열려 있는지 확인하고, 열려 있다면 close()를 호출합니다. 그런 다음 "Cleanup complete"를 출력합니다.

finally 블록은 작업의 성공 여부와 관계없이 정리가 수행되도록 보장합니다. 이 패턴은 처리 중에 어떤 일이 발생하더라도 정리가 반드시 이루어져야 하는 파일, 데이터베이스 연결 또는 네트워크 소켓과 같은 리소스를 관리하는 데 필수적입니다.

치트 시트

예외를 적절하게 처리하고 정리 코드가 항상 실행되도록 하려면 try-catch-finally를 사용하세요:

<?php
try {
    // code that might throw an exception
} catch (ExceptionType $e) {
    // handle the exception
    echo $e->getMessage();
}

별도의 catch 블록을 사용하여 여러 예외 유형을 포착할 수 있습니다. 더 구체적인 예외를 먼저 배치하세요:

<?php
try {
    // risky code
} catch (InvalidArgumentException $e) {
    echo "Bad input: " . $e->getMessage();
} catch (Exception $e) {
    echo "Something went wrong: " . $e->getMessage();
}

finally 블록은 예외가 발생하거나 포착되었는지 여부와 관계없이 실행되므로 정리 작업에 이상적입니다:

<?php
try {
    // attempt operation
} catch (Exception $e) {
    // handle error
} finally {
    // cleanup code runs always
}

직접 해보기

<?php
require_once 'FileProcessor.php';

// 입력 읽기
$filename = trim(fgets(STDIN));

// TODO: FileProcessor 인스턴스 생성

// TODO: try-catch-finally 구조 사용:
// - try 블록: filename으로 open()을 호출한 다음 process() 호출
// - 먼저 FileException을 catch하고 "File error: [message]" 출력
// - RuntimeException을 catch하고 "Runtime error: [message]" 출력
// - finally 블록: isOpen()을 사용하여 파일이 열려 있는지 확인하고, 열려 있으면 close() 호출
//   그 후 "Cleanup complete" 출력

?>
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

객체 지향 프로그래밍의 모든 레슨