PHP에서 데이터베이스 작업을 수행할 때 bindParam과 bindValue는 가장 많이 사용되는 내장 함수입니다. 두 함수 모두 PDO(PHP Data Objects)의 PDOStatement 객체를 통해 SQL 문의 변수와 값을 매핑하여 데이터베이스 레코드에 접근하는 역할을 하며, PDO는 데이터베이스 쿼리를 위한 추상화 계층이라고 할 수 있습니다.
두 함수는 비슷해 보이지만 내부 동작 방식에 중요한 차이가 있으며, 이 차이를 제대로 이해하지 못하면 예상치 못한 버그를 만날 수 있습니다. 아래에서 핵심 차이점을 하나씩 살펴보겠습니다.
bindParam과 bindValue의 주요 차이점
| 번호 | 구분 | bindParam | bindValue |
|---|---|---|---|
| 1 | 정의 | SQL 문에서 지정된 변수명에 파라미터(변수 참조)를 바인딩하는 PHP 내장 함수입니다. | SQL 문에서 지정된 변수명에 파라미터의 '값'을 바인딩하는 PHP 내장 함수입니다. |
| 2 | 실행 시점 | 문(statement)이 실제로 실행되는 시점, 즉 $stmt->execute()가 호출될 때 평가됩니다. | 함수가 선언되는 시점에 값이 할당되고 컴파일됩니다. |
| 3 | 사용되는 값 | 실행 시점에 평가되므로 파라미터에 매핑된 '최신 값'이 문에 적용됩니다. | 선언 시점에 값이 고정되므로 선언 당시의 '초기 값'만 사용됩니다. |
| 4 | 실행 유형 | 런타임(runtime) 실행 방식입니다. | 컴파일(compile) 실행 방식입니다. |
| 5 | 값 변경 | 바인딩 후에도 파라미터 값을 수정할 수 있으며, 수정된 값이 실행에 그대로 반영됩니다. | 바인딩 후에는 값을 수정할 수 없으며, 오직 초기 값만 실행에 사용됩니다. |
코드 예제로 이해하기
bindParam 사용 예
$stmt = $pdo->prepare('SELECT * FROM users WHERE id = :id');
$id = 1;
$stmt->bindParam(':id', $id);
$id = 2; // 값 변경 가능
$stmt->execute(); // id = 2로 실행됨bindParam은 변수 자체를 참조(reference)로 바인딩하기 때문에 execute()가 호출되는 시점의 최신 값이 사용됩니다.
bindValue 사용 예
$stmt = $pdo->prepare('SELECT * FROM users WHERE id = :id');
$id = 1;
$stmt->bindValue(':id', $id);
$id = 2; // 실행 결과에 영향 없음
$stmt->execute(); // id = 1로 실행됨반면 bindValue는 호출 시점의 값을 복사하여 바인딩하므로, 이후 변수가 변경되더라도 실행 결과에는 아무런 영향을 주지 않습니다.
언제 어떤 함수를 사용해야 할까?
반복문 안에서 같은 SQL 문을 여러 번 실행하면서 매번 다른 값을 바인딩해야 한다면 bindParam이 적합합니다. 반대로 고정된 값을 한 번만 바인딩하면 되는 경우라면 bindValue가 더 간단하고 직관적입니다. 또한 bindParam은 변수 참조를 필수로 요구하기 때문에 숫자나 문자열 같은 리터럴 값을 직접 전달할 수 없으며, 이런 경우에는 반드시 bindValue를 사용해야 합니다.