MySQL 데이터베이스를 사용하여 개발할 때 MySQLI_Result는 일반적으로 사용되는 클래스로 쿼리 결과를 캡슐화하여 개발자가 일련의 FCTE_* 메소드를 통해 결과에서 데이터를 추출 할 수 있습니다. 그러나 많은 개발자들이 이러한 방법을 사용할 때 문제가 발생합니다. Fetch_* 메소드를 여러 번 호출 한 후 쿼리 결과는 "사라지는"것처럼 보이며 다시 액세스 할 수 없습니다. 무슨 일이야? 더 깊이 살펴 보겠습니다.
MySQL 쿼리가 실행 된 후 리턴 된 결과 세트가 MySQLI_Result 객체에 캡슐화됩니다. PHP에서는 다음과 같은 다른 fetch_* 메소드를 호출하여 데이터를 라인별로 읽을 수 있습니다.
fetch_assoc () : 결과 행을 연관 배열에서 반환합니다.
fetch_row () : 인덱싱 배열 방식으로 결과 행을 반환합니다.
fetch_object () : 결과 행을 객체로 반환합니다.
예를 들어:
$conn = new mysqli("localhost", "user", "password", "database");
$query = "SELECT * FROM users";
$result = $conn->query($query);
현재 $ result 객체는 mysqli_result 이며 위의 fetch_* 메소드를 호출하는 데 사용할 수 있습니다.
mysqli_result 객체가 fetch_* 메소드를 호출하면 실제로 데이터를 라인별로 읽습니다. fetch_* 메소드를 호출하면 결과 세트에 대한 포인터가 앞으로 이동합니다. 즉, Fetch_*가 호출 될 때마다 데이터 행이 소비되고 포인터의 위치가 업데이트됨을 의미합니다. Fetch_* 메서드를 여러 번 호출하면 더 이상 읽을 데이터가 없을 때까지 줄별로 읽습니다.
예를 들어:
while ($row = $result->fetch_assoc()) {
// 처리 데이터
}
while ($row = $result->fetch_assoc()) {
// 여기에는 데이터가 없습니다,이전 쿼리가 결과 세트를 완전히 소비했기 때문에
}
위에서 볼 수 있듯이 첫 번째 While 루프는 모든 데이터를 읽고 전체 결과 세트를 소비합니다. 두 번째 while 루프가 데이터를 다시 얻으려고 할 때 결과 세트는 "먹어"되었으므로 데이터를 얻을 수 없습니다.
이를 피하기 위해 다음 방법을 수행 할 수 있습니다.
결과 세트를 다시 전환 해야하는 경우 MySQLI_DATA_SEEK () 메소드를 사용하여 데이터 포인터를 재설정 할 수 있습니다. 예를 들어:
$result = $conn->query("SELECT * FROM users");
while ($row = $result->fetch_assoc()) {
// 처음으로 데이터를 읽으십시오
}
// 결과 세트 포인터 재설정
$result->data_seek(0);
while ($row = $result->fetch_assoc()) {
// 두 번째로 데이터를 읽으십시오
}
Data_Seek (0)을 호출하면 결과 세트의 시작 부분으로 데이터 포인터를 다시 재설정하여 데이터를 다시 읽을 수 있습니다.
모든 데이터를 한 번에 가져 오려면 mysqli_fetch_all () 메소드를 사용할 수 있습니다.이 메소드는 Fetch_* 와 같은 줄별로 읽지 않고 모든 데이터를 한 번에 배열로 추출합니다. 예를 들어:
$result = $conn->query("SELECT * FROM users");
$rows = $result->fetch_all(MYSQLI_ASSOC);
// 여러 번 사용할 수 있습니다 $rows 배열의 데이터
foreach ($rows as $row) {
// 처리 데이터
}
이 접근법은 결과 세트가 라인별로 읽고 결과 세트를 소비하는 상황을 피하여 결과 세트 데이터를 여러 위치에서 사용할 수 있습니다.
쿼리 결과가 작 으면 데이터를 배열에 저장하고 배열에서 데이터를 재사용 할 수도 있습니다. 예를 들어:
$result = $conn->query("SELECT * FROM users");
$data = [];
while ($row = $result->fetch_assoc()) {
$data[] = $row;
}
// 여러 번 사용할 수 있습니다 $data 정렬
foreach ($data as $row) {
// 처리 데이터
}
이 방법은 또한 데이터베이스의 반복 쿼리를 피하고 결과 세트의 문제가 "먹는"문제를 피합니다.
Fetch_* 메서드를 여러 번 호출하면 결과 세트가 줄별로 읽고 소비됩니다. 결과 세트를 여러 번 통과하려면 MySQLI_DATA_SEEK ()를 사용하여 결과 세트 포인터를 재설정하거나 MySQLI_Fetch_all ()을 사용하여 모든 데이터를 한 번에 가져 오면 좋은 선택입니다. 이러한 방법을 통해 개발 중에 발생하는 "결과 세트가 먹는"문제를 피하고 데이터가 올바르게 읽히도록 할 수 있습니다.