정의되지 않은 메소드 호출 mysqli_stmt :: get_result
PHP정의되지 않은 메소드 호출 mysqli_stmt :: get_result
내 코드는 다음과 같습니다.
include 'conn.php';
$conn = new Connection();
$query = 'SELECT EmailVerified, Blocked FROM users WHERE Email = ? AND SLA = ? AND `Password` = ?';
$stmt = $conn->mysqli->prepare($query);
$stmt->bind_param('sss', $_POST['EmailID'], $_POST['SLA'], $_POST['Password']);
$stmt->execute();
$result = $stmt->get_result();
마지막 줄에 다음과 같이 오류가 발생합니다 : 정의되지 않은 메서드 호출 mysqli_stmt :: get_result ()
conn.php의 코드는 다음과 같습니다.
define('SERVER', 'localhost');
define('USER', 'root');
define('PASS', 'xxxx');
define('DB', 'xxxx');
class Connection{
/**
* @var Resource
*/
var $mysqli = null;
function __construct(){
try{
if(!$this->mysqli){
$this->mysqli = new MySQLi(SERVER, USER, PASS, DB);
if(!$this->mysqli)
throw new Exception('Could not create connection using MySQLi', 'NO_CONNECTION');
}
}
catch(Exception $ex){
echo "ERROR: ".$e->getMessage();
}
}
}
이 줄을 쓰면 :
if(!stmt) echo 'Statement prepared'; else echo 'Statement NOT prepared';
'Statement NOT prepared'가 인쇄됩니다. IDE에서 직접 쿼리를 실행하면 어떻게됩니까? 가치와 마크, 그것은 잘 작동합니다. $ conn 개체는 프로젝트의 다른 쿼리에서 잘 작동합니다.
어떤 도움을 주시기 바랍니다 .......
해결법
-
==============================
1.
이 방법에 대한 사용자 참고 사항을 읽으십시오.
http://php.net/manual/en/mysqli-stmt.get-result.php
mysqlnd 드라이버가 필요합니다 ... webspace에 설치되어 있지 않으면 BIND_RESULT & FETCH와 함께 작업해야합니다!
https://secure.php.net/manual/en/mysqli-stmt.bind-result.php
https://secure.php.net/manual/en/mysqli-stmt.fetch.php
-
==============================
2.
따라서 MySQL 네이티브 드라이버 (mysqlnd) 드라이버를 사용할 수 없으므로 bind_result를 사용하고 get_result 대신 fetch를 사용하면 코드가 다음과 같이됩니다.
include 'conn.php'; $conn = new Connection(); $query = 'SELECT EmailVerified, Blocked FROM users WHERE Email = ? AND SLA = ? AND `Password` = ?'; $stmt = $conn->mysqli->prepare($query); $stmt->bind_param('sss', $_POST['EmailID'], $_POST['SLA'], $_POST['Password']); $stmt->execute(); $stmt->bind_result($EmailVerified, $Blocked); while ($stmt->fetch()) { /* Use $EmailVerified and $Blocked */ } $stmt->close(); $conn->mysqli->close();
-
==============================
3.
시스템에 mysqlnd 드라이버가 없습니다!
(Debian / Ubuntu 기반) 서버에 새로운 패키지를 설치할 수 있으면, 드라이버를 설치하십시오 :
sudo apt-get install php5-mysqlnd
그런 다음 웹 서버를 다시 시작하십시오.
sudo /etc/init.d/apache2 restart
-
==============================
4.
$ result = stmt-> get_result () 대신에 $ result-> fetch_assoc ()을 모방하지만 stmt 객체를 직접 사용하는이 함수를 만들었습니다 :
function fetchAssocStatement($stmt) { if($stmt->num_rows>0) { $result = array(); $md = $stmt->result_metadata(); $params = array(); while($field = $md->fetch_field()) { $params[] = &$result[$field->name]; } call_user_func_array(array($stmt, 'bind_result'), $params); if($stmt->fetch()) return $result; } return null; }
알 수 있듯이 내부적으로 $ stmt-> fetch ()를 사용하기 때문에 배열을 생성하고 행 데이터를 가져옵니다. mysqli_result :: fetch_assoc을 호출하는 것처럼 호출 할 수 있습니다 ($ stmt 객체 열려 있고 결과가 저장 됨) :
//mysqliConnection is your mysqli connection object if($stmt = $mysqli_connection->prepare($query)) { $stmt->execute(); $stmt->store_result(); while($assoc_array = fetchAssocStatement($stmt)) { //do your magic } $stmt->close(); }
이것이 도움이되기를 바랍니다.
-
==============================
5.
나는 이것이 실제로 문제가 무엇인지에 관해서 이미 답을 얻었음을 알고 있지만 간단한 해결책을 제시하고자한다.
get_results () 메서드를 사용하고 싶었지만 드라이버가 없으며 추가 할 수있는 곳이 아닙니다. 내가 전화하기 전에
$stmt->bind_results($var1,$var2,$var3,$var4...etc);
나는 빈 배열을 만든 다음 그 배열의 키로 결과를 바인딩했습니다.
$result = array(); $stmt->bind_results($result['var1'],$result['var2'],$result['var3'],$result['var4']...etc);
그 결과는 쉽게 메서드에 전달되거나 추가 사용을 위해 객체로 캐스팅 될 수 있습니다.
희망이 비슷한 일을 찾고있는 사람을 도울 수 있기를 바랍니다.
-
==============================
6.
여기 내 대안이 있습니다. 이것은 객체 지향적이며 mysql / mysqli와 더 비슷합니다.
class MMySqliStmt{ private $stmt; private $row; public function __construct($stmt){ $this->stmt = $stmt; $md = $stmt->result_metadata(); $params = array(); while($field = $md->fetch_field()) { $params[] = &$this->row[$field->name]; } call_user_func_array(array($stmt, 'bind_result'), $params) or die('Sql Error'); } public function fetch_array(){ if($this->stmt->fetch()){ $result = array(); foreach($this->row as $k => $v){ $result[$k] = $v; } return $result; }else{ return false; } } public function free(){ $this->stmt->close(); } }
용법:
$stmt = $conn->prepare($str); //...bind_param... and so on if(!$stmt->execute())die('Mysql Query(Execute) Error : '.$str); $result = new MMySqliStmt($stmt); while($row = $result->fetch_array()){ array_push($arr, $row); //for example, use $row['id'] } $result->free(); //for example, use the $arr
-
==============================
7.
나는이 질문에 어떤 새로운 활동이 있었기 때문에 오랜 시간이 걸렸다는 것을 알고 있습니다. 그러나 다른 포스터가 주석을 달았 기 때문에 get_result ()는 MySQL 기본 드라이버 (mysqlnd)를 설치하여 PHP에서만 사용할 수 있으며 경우에 따라 mysqlnd를 설치하는 것이 바람직하지 않을 수도 있습니다. 그래서 get_result ()를 사용하지 않고 get_result ()가 제공하는 기능을 얻는 방법에 대한 정보를 제공하여이 답변을 게시하는 것이 도움이 될 것이라고 생각했습니다.
get_result ()는 fetch_array ()와 결합되어 결과 집합을 반복하고 결과 집합의 각 행에있는 값을 숫자로 색인 된 또는 연관 배열에 저장합니다. 예를 들어, 아래의 코드는 fetch_array ()와 함께 get_result ()를 사용하여 결과 집합을 순환하여 숫자로 인덱싱 된 $ data [] 배열에 각 행의 값을 저장합니다.
$c=1000; $sql="select account_id, username from accounts where account_id<?"; $stmt = $mysqli->prepare($sql); $stmt->bind_param('i', $c); $stmt->execute(); $result = $stmt->get_result(); while($data = $result->fetch_array(MYSQLI_NUM)) { print $data[0] . ', ' . $data[1] . "<BR>\n"; }
그러나 get_result ()를 사용할 수 없으면 (mysqlnd가 설치되지 않았기 때문에) get_result ()를 사용하지 않고 결과 집합의 각 행에있는 값을 배열에 저장하는 방법에 문제가 발생합니다. 또는 get_result ()를 사용하는 레거시 코드를 마이그레이션하지 않고 (예 : bind_result () 사용) - 나머지 코드는 가능한 한 최소화하는 방법.
수치 적으로 배열 된 배열에 각 행의 값을 저장하는 것은 bind_result ()를 사용하여 그렇게 간단하지는 않습니다. bind_result ()는 배열이 아닌 스칼라 변수 목록을 필요로합니다. 따라서 결과 집합의 각 행에있는 값을 배열에 저장하는 작업이 필요합니다.
물론이 코드는 다음과 같이 쉽게 수정할 수 있습니다.
$c=1000; $sql="select account_id, username from accounts where account_id<?"; $stmt = $mysqli->prepare($sql); $stmt->bind_param('i', $c); $stmt->execute(); $stmt->bind_result($data[0], $data[1]); while ($stmt->fetch()) { print $data[0] . ', ' . $data[1] . "<BR>\n"; }
그러나 이것은 우리가 $ data [0], $ data [1] 등을 개별적으로 bind_result ()를 호출 할 때 명시 적으로 나열해야하므로 이상적이지 않습니다. 우리는 $ data [0], $ data [1], ... $ data [N-1] (N은 select 문의 필드의 수)를 명시 적으로 나열 할 필요가없는 솔루션을 원합니다. bind_results () 호출에서. 많은 수의 쿼리가있는 레거시 애플리케이션을 마이그레이션 할 때 각 쿼리에 select 절에 다른 개수의 필드가 포함되는 경우 마이그레이션과 같은 솔루션을 사용하면 마이그레이션이 매우 노동 집약적이며 오류가 발생하기 쉽습니다. 위.
이상적으로는 get_result () 함수와 다음 줄의 while () 루프가 포함 된 줄만 바꾸는 '드롭 인 대체 코드'스 니펫이 필요합니다. 교체 코드는 이전의 행이나 이후의 행에 영향을주지 않고 대체 할 코드와 동일한 기능을 가져야합니다. while () 루프 내부의 행을 포함합니다. 이상적으로는 대체 코드가 가능한 한 작아지기를 바라고 쿼리의 select 절에있는 필드 수에 따라 교체 코드를 테일러하지 않아도됩니다.
인터넷에서 검색 한 결과, bind_param ()을 call_user_func_array ()와 함께 사용하는 많은 솔루션을 발견했습니다. (예를 들어, mysqli_stmt 매개 변수를 동적으로 바인드 한 다음 result (PHP)를 바인드), 결과적으로 발견 된 대부분의 솔루션은 결과적으로 인덱스 배열이 아닌 연관 배열에 저장되며 많은 해결책은 컴팩트 한 크기로, "드롭 인 대체"로 적합하지 않았습니다. 그러나 내가 찾은 사례에서 나는이 해결책을 함께 쓸 수 있었다.
$c=1000; $sql="select account_id, username from accounts where account_id<?"; $stmt = $mysqli->prepare($sql); $stmt->bind_param('i', $c); $stmt->execute(); $data=array(); for ($i=0;$i<$mysqli->field_count;$i++) { $var = $i; $$var = null; $data[$var] = &$$var; } call_user_func_array(array($stmt,'bind_result'), $data); while ($stmt->fetch()) { print $data[0] . ', ' . $data[1] . "<BR>\n"; }
물론, for () 루프는 좀 더 컴팩트하게 만들기 위해 하나의 줄로 축소 될 수 있습니다.
이 방법으로 bind_result ()를 사용하여 솔루션을 찾고자하는 사람들이 숫자로 색인 된 배열에있는 각 행의 값을 저장하거나 get_result ()를 사용하여 레거시 코드를 마이그레이션하는 방법을 찾고자 할 때 도움이되기를 바랍니다. 의견 환영합니다.
-
==============================
8.
$ stmt-> get_result ();와 동일한 기능을 제공하는 두 개의 간단한 함수를 작성했지만 mysqlnd 드라이버는 필요하지 않습니다.
당신은 단순히
$ 결과 = $ stmt-> get_result (); $ fields = bindAll ($ stmt);와 함께;
과
$ row = $ stmt-> get_result (); $ row = fetchRowAssoc ($ stmt, $ fields);와 함께.
(반환 된 행의 수를 얻으려면 $ stmt-> num_rows를 사용할 수 있습니다.)
방금 작성한이 두 함수를 PHP 스크립트에 배치하면됩니다. (예 : 오른쪽 하단)
function bindAll($stmt) { $meta = $stmt->result_metadata(); $fields = array(); $fieldRefs = array(); while ($field = $meta->fetch_field()) { $fields[$field->name] = ""; $fieldRefs[] = &$fields[$field->name]; } call_user_func_array(array($stmt, 'bind_result'), $fieldRefs); $stmt->store_result(); //var_dump($fields); return $fields; } function fetchRowAssoc($stmt, &$fields) { if ($stmt->fetch()) { return $fields; } return false; }
작동 원리 :
내 코드는 $ stmt-> result_metadata (); 함수를 사용하여 반환되는 필드의 수와 개수를 파악한 다음 가져온 결과를 미리 만들어진 참조에 자동 바인딩합니다. 매력처럼 작동합니다!
-
==============================
9.
mysqlnd 확장 기능이 이미 활성화 된 상태에서 PHP 7.0과 동일한 오류가 발생했습니다.
해결책은 나를위한 것이 었습니다 (이 페이지 덕분에) mysqli 확장을 선택 해제하고 대신 nd_mysqli를 선택했습니다.
NB - cPanel의 확장 프로그램 선택기에 액세스 할 수 있습니다. (Select PHP Version 옵션을 통해 광산에 액세스합니다.)
from https://stackoverflow.com/questions/8321096/call-to-undefined-method-mysqli-stmtget-result by cc-by-sa and MIT lisence
'PHP' 카테고리의 다른 글
PHP 치명적인 오류를 어떻게 잡을 수 있습니까? (0) | 2018.09.02 |
---|---|
문자열에 특정 단어가 포함되어 있는지 어떻게 확인합니까? (0) | 2018.09.02 |
mysql_fetch_array () / mysql_fetch_assoc () / mysql_fetch_row () / mysql_num_rows 등 ... 매개 변수 1이 리소스가 될 것으로 예상 함 (0) | 2018.09.02 |
PHP에서 전체 URL 가져 오기 (0) | 2018.09.02 |
로컬 호스트에서 메일을 보내도록 XAMPP를 구성하는 방법? (0) | 2018.09.02 |