MySQLi에서 Named Parameter처럼 사용할 수 있도록 변환하는 사용자 함수
문자열:s 숫자:i 이렇게 사용하는 방식은 파라미터가 많으면 복잡해서 알아보기 힘들죠
그래서 만들어진 사용자 함수 입니다.
# MySQLi에서 Named Parameter처럼 사용할 수 있도록 변환하는 사용자 함수
function prepareNamedQuery($mysqliCon, string $sql, $params) {
preg_match_all('/:\w+/', $sql, $matches);
$namedParams = $matches[0];
$sql = str_replace($namedParams, '?', $sql);
$values = [];
$types = '';
foreach ($namedParams as $param) {
$key = substr($param, 1);
if (!isset($params[$key])) {
throw new Exception("파라미터 {$key}가 없습니다.");
}
$values[] = $params[$key];
// 데이터 타입 설정
if (is_int($params[$key])) {
$types .= 'i';
} elseif (is_float($params[$key])) {
$types .= 'd';
} else {
$types .= 's';
}
}
$stmt = $mysqliCon->prepare($sql);
if (!$stmt) {
throw new Exception("SQL 준비 오류: " . $mysqliCon->error);
}
if ($values) {
$stmt->bind_param($types, ...$values);
}
return $stmt;
}
# 예
$mysqliCon = new mysqli("localhost", "user", "password", "test");
$sql = "SELECT * FROM test.일봉치 WHERE test11 = :stockCode LIMIT :갯수";
$params = [
"stockCode" => "000020",
"갯수" => 3
];
$stmt = prepareNamedQuery($mysqliCon, $sql, $params);
$stmt->execute();
$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) {
print_r($row);
}
$stmt->close();
$mysqliCon->close();
이게 PDO를 사용할 경우 (Named Parameter 지원) 하기 때문에 PDO를 사용하면 이런 함수가 필요 없는데
저처럼 사용하지 않는 경우 필요하기 때문에 만들어진 함수 입니다.
:파라미터명 형식을 ?로 변환하고, bind_param()에 맞게 적용하는 함수를 구현
● 처리 순서
- SQL에서 :변수명을 찾아 ?로 변환
- 해당 변수 값을 bind_param()에 맞게 배열에 저장
- 최종적으로 변환된 SQL과 함께 bind_param() 실행
왜? 이런 방식을 사용할까 궁금하신 분이 있을것 같은데 SQL을 통한 해킹을 예방 하고자 하면 필요한 방식 입니다.
SQL 명령 문과 사용자가 입력하는 값을 분리하는 방식으로 기존의 SQL 쿼리 문에 문자열을 합쳐서 처리하는 방식과 근본적으로 다르기 때문에 SQL 인젝션 공격에 대해 안심 할 수 있습니다.