정의되지 않은 메서드 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 ready'를 인쇄합니다 . IDE에서 직접 쿼리를 실행하면? 값으로 표시하면 제대로 작동합니다. $ conn 개체는 프로젝트의 다른 쿼리에서 잘 작동합니다.
도와주세요 .......
이 방법에 대한 사용자 참고 사항을 읽으십시오.
http://php.net/manual/en/mysqli-stmt.get-result.php
mysqlnd 드라이버가 필요합니다 ... 웹 공간에 설치되어 있지 않으면 BIND_RESULT & FETCH로 작업해야합니다!
https://secure.php.net/manual/en/mysqli-stmt.bind-result.php
https://secure.php.net/manual/en/mysqli-stmt.fetch.php
MySQL의 기본 드라이버 (mysqlnd) 드라이버를 사용할 수 있으므로 사용하지 않는 경우에 따라서 bind_result을 하고 가져 오는 대신 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();
$stmt->bind_result($EmailVerified, $Blocked);
while ($stmt->fetch())
{
/* Use $EmailVerified and $Blocked */
}
$stmt->close();
$conn->mysqli->close();
시스템에 mysqlnd 드라이버가 없습니다!
(Debian / Ubuntu 기반) 서버에 새 패키지를 설치할 수있는 경우 드라이버를 설치합니다.
sudo apt-get install php5-mysqlnd
그런 다음 웹 서버를 다시 시작하십시오.
sudo /etc/init.d/apache2 restart
$ 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();
}
도움이 되었기를 바랍니다.
나는 이것이 실제 문제에 대해 이미 답변을 받았음을 알고 있지만 간단한 해결 방법을 제공하고 싶습니다.
get_results () 메서드를 사용하고 싶었지만 드라이버가 없었고 추가 할 수있는 곳이 아닙니다. 그래서 내가 전화하기 전에
$stmt->bind_results($var1,$var2,$var3,$var4...etc);
빈 배열을 만든 다음 결과를 해당 배열의 키로 바인딩했습니다.
$result = array();
$stmt->bind_results($result['var1'],$result['var2'],$result['var3'],$result['var4']...etc);
따라서 이러한 결과를 쉽게 메서드로 전달하거나 나중에 사용하기 위해 객체로 캐스팅 할 수 있습니다.
이것이 비슷한 일을하려는 사람에게 도움이되기를 바랍니다.
PHP 버전 7.2 에서는 mysqli 대신 nd_mysqli 를 사용 했으며 예상대로 작동했습니다.
GoDaddy 호스팅 서버에서 활성화하는 단계-
- cpanel에 로그인합니다.
- "Select PHP version"을 클릭합니다 .
- 최신 구성의 스냅 샷이 제공된대로 "mysqli"를 선택 취소 하고 "nd_mysqli"를 활성화 합니다.
mysqlnd 확장이 이미 활성화 된 PHP 7.0- 내 서버에서 동일한 오류가 발생했습니다 .
해결책은 ( 이 페이지 덕분에 ) mysqli 확장 을 선택 취소하고 대신 nd_mysqli 를 선택하는 것이 었 습니다.
주의-cPanel에서 확장 선택기에 액세스 할 수 있습니다. ( PHP 버전 선택 옵션을 통해 액세스 합니다.)
I realize that it's been a while since there has been any new activity on this question. But, as other posters have commented - get_result()
is now only available in PHP by installing the MySQL native driver (mysqlnd), and in some cases, it may not be possible or desirable to install mysqlnd. So, I thought it would be helpful to post this answer with info on how get the functionality that get_result()
offers - without using get_result()
.
get_result()
is/was often combined with fetch_array()
to loop through a result set and store the values from each row of the result set in a numerically-indexed or associative array. For example, the code below uses get_result() with fetch_array() to loop through a result set, storing the values from each row in the numerically-indexed $data[] array:
$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";
}
However, if get_result()
is not available (because mysqlnd is not installed), then this leads to the problem of how to store the values from each row of a result set in an array, without using get_result()
. Or, how to migrate legacy code that uses get_result()
to run without it (e.g. using bind_result()
instead) - while impacting the rest of the code as little as possible.
It turns out that storing the values from each row in a numerically-indexed array is not so straight-forward using bind_result()
. bind_result()
expects a list of scalar variables (not an array). So, it takes some doing to make it store the values from each row of the result set in an array.
Of course, the code could easily be modified as follows:
$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";
}
But, this requires us to explicitly list $data[0], $data[1], etc. individually in the call to bind_result()
, which is not ideal. We want a solution that doesn't require us to have to explicitly list $data[0], $data[1], ... $data[N-1] (where N is the number of fields in the select statement) in the call to bind_results()
. If we're migrating a legacy application that has a large number of queries, and each query may contain a different number of fields in the select
clause, the migration will be very labor intensive and prone to error if we use a solution like the one above.
Ideally, we want a snippet of 'drop-in replacement' code - to replace just the line containing the get_result()
function and the while() loop on the next line. The replacement code should have the same function as the code that it's replacing, without affecting any of the lines before, or any of the lines after - including the lines inside the while() loop. Ideally we want the replacement code to be as compact as possible, and we don't want to have to taylor the replacement code based on the number of fields in the select
clause of the query.
Searching on the internet, I found a number of solutions that use bind_param()
with call_user_func_array()
(for example, Dynamically bind mysqli_stmt parameters and then bind result (PHP)), but most solutions that I found eventually lead to the results being stored in an associative array, not a numerically-indexed array, and many of these solutions were not as compact as I would like and/or were not suited as 'drop-in replacements'. However, from the examples that I found, I was able to cobble together this solution, which fits the bill:
$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";
}
Of course, the for() loop can be collapsed into one line to make it more compact.
I hope this helps anyone who is looking for a solution using bind_result()
to store the values from each row in a numerically-indexed array and/or looking for a way to migrate legacy code using get_result()
. Comments welcome.
Here is my alternative. It is object-oriented and is more like mysql/mysqli things.
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();
}
}
Usage:
$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
I have written two simple functions that give the same functionality as $stmt->get_result();
, but they don't require the mysqlnd driver.
You simply replace
$result = $stmt->get_result();
with $fields = bindAll($stmt);
and
$row= $stmt->get_result();
with $row = fetchRowAssoc($stmt, $fields);
.
(To get the numbers of returned rows you can use $stmt->num_rows
.)
You just have to place these two functions I have written somewhere in your PHP Script. (for example right at the bottom)
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;
}
How it works:
내 코드는 $stmt->result_metadata();
함수를 사용하여 반환되는 필드 수와 필드를 파악한 다음 가져온 결과를 미리 생성 된 참조에 자동으로 바인딩합니다. 매력처럼 작동합니다!
참고 URL : https://stackoverflow.com/questions/8321096/call-to-undefined-method-mysqli-stmtget-result
'Programming' 카테고리의 다른 글
앱이 설정되지 않음 :이 앱은 아직 개발 모드입니다. (0) | 2020.08.10 |
---|---|
CSS 이미지 미리로드 (0) | 2020.08.10 |
전체 라인을 sed로 바꾸는 방법? (0) | 2020.08.10 |
디렉토리에 파일이 포함되어 있는지 쉘 스크립트에서 확인 (0) | 2020.08.10 |
프로그래밍 방식으로 UITableView 섹션 제목을 설정하는 방법 (iPhone / iPad)? (0) | 2020.08.10 |