데이터베이스 프로그래밍에 PHP의 MySQLI 확장을 사용할 때 개발자는 때때로 혼란스러운 상황에 직면합니다. mysqli :: stmt_init () 호출은 명령문 객체를 성공적으로 초기화하지만 후속 준비 () 메소드에서 실패합니다. 이 상황은 비논리적 인 것처럼 보이지만 실제로는 여러 수준의 이유가 포함됩니다. 이 기사는이 문제에 대한 일반적인 원인과 솔루션을 자세히 분석합니다.
mysqli :: stmt_init ()는 빈 mysqli_stmt 객체를 만드는 데 사용됩니다. 데이터베이스와의 상호 작용을 수행하지는 않지만 후속 SQL 작업 만 준비하고 있습니다. Prepar () 메소드는 사전 컴파일을 위해 SQL 문을 데이터베이스 서버로 보냅니다. 구문이 잘못되었거나 데이터베이스 구성이 잘못된 경우 repay ()는 false를 반환합니다.
$mysqli = new mysqli("localhost", "user", "password", "database");
$stmt = $mysqli->stmt_init(); // 초기화가 성공적으로
if ($stmt->prepare("SELECT * FROM users WHERE id = ?")) {
echo "Prepare 성공";
} else {
echo "Prepare 실패하다: " . $stmt->error;
}
이것이 가장 일반적인 이유 중 하나입니다. STMT_INIT () 가 성공하지만 ready () 에 전달 된 SQL에 구문 오류가 있으면 MySQL은 사전 컴파일을 거부하여 repay () 실패를 초래합니다.
샘플 오류 SQL :
SELECT FROM users WHERE id = ?
글을 쓰는 올바른 방법은 다음과 같습니다.
SELECT * FROM users WHERE id = ?
MySQL의 준비된 명령문은 모든 유형의 SQL 문을 지원하지는 않습니다. 예를 들어, 테이블 , 드롭 , ALTER 및 기타 문은 repay ()를 사용할 수 없습니다. 이 작업을 시도하면 repay () 도 실패를 반환합니다.
SQL에 존재하지 않는 테이블이나 필드가 참조되면 구문 오류를 구성하지는 않지만 서버가 컴파일을 거부하여 준비 () 가 오류를보고하게 할 수도 있습니다.
$stmt->prepare("SELECT age FROM userz WHERE id = ?"); // 잘못된 테이블 이름 'userz'
MySQLI 객체를 호출 할 때 연결이 연결이 끊어 지거나 유효하지 않은 경우 STMT_INIT ()가 즉시 오류가 발생하지는 않지만 서버와 상호 작용하려고 시도하면 준비 ()가 실패합니다.
데이터베이스 사용자는 특정 테이블에 대한 선택 권한이 없어서 전처리 명세서가 대상 데이터 테이블에 액세스하지 못하므로 repay () 시 실패합니다.
테이블 이름, 열 이름 등이 MySQL 예약 된 단어를 사용하지만 백 티크 ( ` )로 랩핑되지 않으면 repay () 시 구문 오류로 인식 될 수도 있습니다.
$stmt->prepare("SELECT select FROM users WHERE id = ?"); // 오류 예제,'select' 예약되어 있습니다
변경 :
$stmt->prepare("SELECT `select` FROM users WHERE id = ?");
오류 메시지를 인쇄합니다 특정 오류 정보를보기 위해 $ stmt-> error 또는 $ mysqli-> 오류를 사용하는 것이 문제 해결의 첫 번째 단계입니다.
오류 보고서를 켜십시오
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
벌채 반출 실패한 SQL 및 오류는 쉽게 개발 및 테스트 단계 분석을 위해 로그 파일에 로그인 할 수 있습니다.
양식 데이터를 제출하기 위해 다음 링크를 방문했다고 가정합니다.
https://m66.net/form/submit.php
양식 처리 로직은 다음과 같습니다.
$mysqli = new mysqli("localhost", "user", "pass", "db");
$mysqli->set_charset("utf8mb4");
$stmt = $mysqli->stmt_init();
if (!$stmt->prepare("INSERT INTO user_data (name, email) VALUES (?, ?)")) {
error_log("Prepare 실패하다: " . $stmt->error); // 기록 오류
die("시스템을 일시적으로 사용할 수 없습니다");
}
$stmt->bind_param("ss", $_POST['name'], $_POST['email']);
$stmt->execute();
user_data 테이블이 존재하지 않거나 필드 이름이 잘못된 철자가 있으면 stmt_init ()가 성공적이지만 repay ()는 오류가 발생합니다.
mysqli :: stmt_init () 는 명세서 개체의 생성자 일 뿐이며 성공이 SQL 자체가 합법적이거나 실행 가능하다는 것을 의미하지는 않습니다. 실제 구문 및 논리 점검은 repary () 단계에서 발생합니다. 오류 메시지 및 우수한 디버깅 습관과 결합 된이를 이해하면 문제의 빠른 위치와 해결이 가능할 수 있습니다.
디버깅 중에 여전히 해결할 수없는 문제에 직면해도 데이터베이스 클라이언트 (예 : PhpmyAdmin 또는 명령 줄)에 SQL을 가져 와서 별도로 테스트하거나 데이터베이스 권한이있는 관리자에게 문의하여 지원을받을 수 있습니다.