ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 에러 핸들링, PHP, mysqli, prepared statement
    간단기법 2023. 5. 17. 16:40

    PHP mysqli prepared statement 에러 핸들링

    PHP에서 데이터베이스를 다루기 위해서 mysqli과 prepared statement를 이용한 코드를 작성한다. 다음과 같은 코드 구조가 일반적이다.

    // db에 연결하여 데이터를 조작하려면 다음과 같은 코드가 필수로 필요하다.
    <?php
    	$con = new mysqli(연결정보...)
        $con->prepare(쿼리);
        $con->bind_param(...);
        $con->execute();
        $result = $con->get_result();
        $row = $result->fetch...();
    ?>

    이 코드를 그대로 쓸 수는 없다. 왜냐하면 에러 핸들링이 전혀 안되어있기 때문이다. 에러 핸들링을 적용한 코드로 바꿔보자.

    // db에 연결하여 데이터를 조작하려면 다음과 같은 코드가 필수로 필요하다.
    <?php
    	$con = new mysqli(연결정보...)
        if($con->connect_errno) {
        	....
            return;
        }
        
        if(!$con->prepare(쿼리)) {
        	...
            return;
        }
        
        if(!con->bind_param(...)) {
        	...
            return;
        }
        
        if(!$con->execute()) {
        	...
            return;
        }
        
        if(!$result = $con->get_result()) {
        	...
            return;
        }
        
        $row = $result->fetch...();
        if(!$row) {
        	...
            return;
        }
        
        
    ?>

    각 단계의 호출마다 리턴값을 확인하여 에러를 체크하는 코드가 들어간다. 상상만 해도 번거롭다. 그리고 이것이 끝이 아니라 mysqli 드라이버에 에러를 어떻게 대할 것인지 설정하는 것에 따라 에러가 발생하면 경고가 뜨기도 하고 예외를 던지기도 한다.

    // 예외
    // new mysqli
    mysqli error report가 켜져있으면 경고를
    MYSQLI_REPORT_STRICT까지 있으면 예외를 발생한다.
    예외의 타입은 mysqli_sql_exception
    
    // prepare, bind_param, execute, get_result, 
    위와 동일
    
    // bind_param
    위와 동일
    
    // execute
    위와동일
    
    // get_result
    prepare와 동일.
    
    // fetch_....
    예외 발생 안함...

     

    위와 같이 많은 것들을 신경써야 하고, 코드는 늘어지게 된다. 이것을 조금이라도 간단하게 하는 방법을 알아보려고 한다. 

    단축평가를 이용한 에러 핸들링

    PHP를 비롯한 여러 언어에는 단축 평가라는 개념이 있다. and 연산자인 &&는 좌측부터 조건이 참인지 거짓인지 판별하는데, 만약 거짓이면 나머지 조건들은 평가하지 않고 넘어가는 것이다. 반대로 ||는 참이라면 나머지 조건들을 평가하지 않고 넘어간다.

     

    && 연산자에 대한 단축평가를 이용하여 에러 핸들링을 할 수 있다. prepare부터 get_result까지 반환값이 ture, false인 것을 이용하는 것이다. 코드는 다음과 같다.

    // db에 연결하여 데이터를 조작하려면 다음과 같은 코드가 필수로 필요하다.
    <?php
    	$con = new mysqli(연결정보...)
        
        if($con->connect_errno == 0 &&
        	$con->prepare() &&
            $con->bind_param() &&
            $con->execute() &&
            $result = $con->get_result() &&
            $row = $result->fetch_..()) {
            // $row를 이용한 코딩
        }
             
    ?>

    다만 이것만으론 약간 부족한 것이 에러가 발생하면, 어떤 에러가 발생했는지 확인해야 하므로 다음과 같은 코드가 if의 else로 들어간다.

    else {
    	// 아래 에러를 확인
        $mysqli->error
        $stmt->error
    }

    예외를 이용한 에러 핸들링

    mysqli 드라이버에 설정을 하는 것에 따라 mysqli 메소드를 호출해서 실패할 때 예외가 발생한다.

    mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

     

    t위와 같은 설정을 하고 진행한다면 실패시 예외가 발생한다. 코드는 다음과 같을 것이다.

    try {
        $stmt = $mysqli->prepare(...);
        $stmt->bind_param(...);
        $stmt->execute();
        
    	// fetch...    
    } catch (mysqli_sql_exception $e) {
        $e->getMessage();
    }

    결론

    예외보다 에러와 에러코드를 확인하는 쪽을 선호하는 편이었다. 각 코드별로 에러가 발생했을 때, 에러가 발생한 지점에서 처리해야 하는 코드를 주로 다뤘기 때문이다. 하지만, 적어도 mysqli와 prepared statement를 이용한다면 예외로 처리하는 쪽이 좋아 보인다. 단계별로 구별해서 처리할 것도 없어 보이고, 코드 자체도 명료해지고, 예외가 발생했을 때 원인도 알기 괜찮기 때문이다.

    참고

    댓글

Designed by Tistory.