정의되지 않은 메서드 mysqli_stmt :: get_result 호출


113

내 코드는 다음과 같습니다.

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 개체는 프로젝트의 다른 쿼리에서 잘 작동합니다.

도와주세요 .......


잊어 버린 것 같아요 $stmt = $conn->mysqli->stmt_init();?
favoretti

$_POST['EmailID'], $_POST['SLA'], $_POST['Password']POST 메소드가있는 HTML 양식을 사용하여 이러한 변수가 올바르게 제출되었는지 확인하십시오
ajreal

@ajreal : 변수가 올바르게 게시되고 있습니다. print_r ($ _ POST)를 사용하여 테스트했습니다.
Kumar Kush 2011

@favoretti : 나는 $ stmt = $ conn-> mysqli-> stmt_init (); . 여전히 운이 없습니다.
Kumar Kush 2011

내가 언급하고 싶은 한 가지는 내가 비슷한 코드를 사용했는데 다른 곳에서 잘 작동한다는 것입니다.
Kumar Kush 2011

답변:


146

이 방법에 대한 사용자 참고 사항을 읽으십시오.

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


4
감사합니다. 작동했습니다. php.ini 에서 extension = php_mysqli_mysqlnd.dll의 주석 처리를 제거했습니다 . Apache2.2 및 MySQL 서비스를 다시 시작했습니다. extension = php_mysqli_libmysql.dll 줄의 주석 처리를 제거해야합니까 ? 다른 페이지에 따르면 mysqlnd는 libmysql보다 빠릅니다. 또한 가장 인기있는 호스팅 서비스 제공 업체에 mysqlnd가 설치 될 것으로 예상 할 수 있습니까?
Kumar Kush 2011

1
stmt_init () 는 절차 상 준비된 명령문에만 필요합니다. 그래서 당신은 그것을 필요로하지 않습니다! 보세요 : link libmysql에 관해서는 : 모르겠습니다. 그리고 mysqlnd.dll 설치를 호스팅 제공 업체에 의존하지 않을 것입니다 .
bekay

2
참고 : mysqli_stmt::get_result()PHP v5.3.0 이상에서만 사용할 수 있습니다.
Raptor

4
@bekay 방금 새 노트북과 새 창을 저장했습니다. +10을 사용할 수있는 경우 제공합니다
James Cushing 2014

1
@ kush.impetus, 어디에서 다운로드 php_mysqli_mysqlnd.dll합니까? php_mysqli.dllext폴더 에만 있습니다 .
Pacerier 2015-06-29

51

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();

$ stmt-> bind_result를 사용하면 시간이 절약됩니다. get_result를 사용할 수없는 경우 훌륭한 솔루션입니다.
Zafer

2
질문 : $ EmailVerfied 변수는 어디에서 왔습니까?
Rotimi

@ Akintunde007 :을 $EmailVerfied호출하여 생성됩니다 bind_result().
AbraCadaver

코드를 사용하여 : "정의되지 않은 방법 mysqli_stmt에 전화 :: bind_results () catch되지 않은 오류"오류 발생 얻기
악마의 꿈

"Select * from table_name"과 같은 SQL 쿼리가있는 경우 bind_result () 내부에서 선언하는 방법. * 운영자
Inderjeet

46

시스템에 mysqlnd 드라이버가 없습니다!

(Debian / Ubuntu 기반) 서버에 새 패키지를 설치할 수 있으면 드라이버를 설치합니다.

sudo apt-get install php5-mysqlnd

그런 다음 웹 서버를 다시 시작하십시오.

sudo /etc/init.d/apache2 restart

39

대안을 찾는 사람들 $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();
}

이것은 여기서 가장 쉬운 드롭 인 대체 답변입니다. 수고하셨습니다 – 감사합니다!
Alex Coleman

많은 시간을 절약했습니다!
Jahaziel

3
$statement->store_result();함수를 호출하기 전에 필요한 경우 함수에 포함하지 않는 이유는 무엇입니까?
InsanityOnABun

감사합니다. 마감일에 내 엉덩이를 구했습니다
Kolob Canyon

20

PHP 버전 7.2 에서는 mysqli 대신 nd_mysqli 를 사용 했습니다. 했으며 예상대로 작동했습니다.

GoDaddy 호스팅 서버에서 활성화하는 단계-

  1. cpanel에 로그인합니다.
  2. "PHP 버전 선택"을 클릭하십시오. .
  3. 최신 구성의 스냅 샷이 제공된대로 "mysqli"를 선택 취소 하고 "nd_mysqli"를 활성화 합니다.

여기에 이미지 설명 입력


2
고마워요, 미쳤어 요!
Ussaid 이크발

1
Haaa, 이것은 내 시간을 절약합니다! 감사합니다!
Nurul Huda

1
큰! cPanel에 대한 완벽한 답변
Rashid

1
정말 고맙습니다!! You save me man, i ca n't thank you enough
Enes Çalışkan

이 답변은 맨 위에 있어야합니다
Rishabh Gusain

10

나는 이것이 실제 문제에 대해 이미 답변을 받았음을 알고 있지만 간단한 해결 방법을 제공하고 싶습니다.

get_results () 메서드를 사용하고 싶었지만 드라이버가 없었고 추가 할 수있는 곳이 아닙니다. 그래서 내가 전화하기 전에

$stmt->bind_results($var1,$var2,$var3,$var4...etc);

빈 배열을 만든 다음 결과를 해당 배열의 키로 바인딩했습니다.

$result = array();
$stmt->bind_results($result['var1'],$result['var2'],$result['var3'],$result['var4']...etc);

따라서 이러한 결과를 쉽게 메서드로 전달하거나 나중에 사용하기 위해 객체로 캐스팅 할 수 있습니다.

이것이 비슷한 일을하려는 사람에게 도움이되기를 바랍니다.


7

mysqlnd 확장이 이미 활성화 된 PHP 7.0- 내 서버에서 동일한 오류가 발생했습니다 .

해결책은 ( 이 페이지 덕분에 ) mysqli 확장 을 선택 취소하고 대신 nd_mysqli 를 선택하는 것이 습니다.

주의-cPanel에서 확장 선택기에 액세스 할 수 있습니다. ( PHP 버전 선택 옵션을 통해 액세스 합니다.)


이것은 받아 들여진 대답이어야합니다. 다른 방법을 사용하기 위해 전체 스크립트를 편집하는 것보다 확장을 활성화하는 것이 훨씬 낫습니다! 아, 그리고 그것은 :) 나를 위해 일한
ArabianMaiden

나는 같은 문제가 있었다. 사실, PHP의 session_start()기능을 사용 하는 것은 나를 존재하지 않는 가치처럼 만들었습니다. 그런 다음 7.2PHP 버전 으로 업그레이드하고 의 확장자 mysqlind_mysqli (고정)으로 변경했습니다 . 하지만 두 가지 질문이 있습니다. 둘의 차이점은 무엇입니까? 해당 확장을 사용하는 데 보안에 공백이 있다면?
jecorrales jul.

6

이 질문에 대한 새로운 활동이 있었던 지 오래되었다는 것을 알고 있습니다. 그러나 다른 포스터가 언급 get_result()했듯이 - 이제는 MySQL 네이티브 드라이버 (mysqlnd)를 설치하여 PHP에서만 사용할 수 있으며 경우에 따라 mysqlnd를 설치하는 것이 가능하지 않거나 바람직하지 않을 수 있습니다. 따라서 .NET을 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()with call_user_func_array() (예 : Dynamically bind mysqli_stmt parameters and then bind 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(). 의견을 환영합니다.


Yupp. 3 년 전에 PDO로 전환했습니다. 어쨌든 고마워.
Kumar Kush

5

여기 내 대안이 있습니다. 그것은이다 객체 지향 및 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

2

동일한 기능을 제공하는 두 개의 간단한 함수를 작성했습니다. $stmt->get_result(); 했지만 mysqlnd 드라이버가 필요하지 않습니다.

당신은 단순히 교체

$result = $stmt->get_result(); $fields = bindAll($stmt);

$row= $stmt->get_result(); $row = fetchRowAssoc($stmt, $fields); .

(반환 된 행 수를 얻으려면 $stmt->num_rows .)

당신은 단지 내가 작성한 이 두 함수를 PHP Script 어딘가에 배치 됩니다. (예 : 오른쪽 하단)

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(); 함수를 반환되는 필드 수와 필드를 파악한 다음 가져온 결과를 미리 생성 된 참조에 자동으로 바인딩합니다. 매력처럼 작동합니다!


왜 반대표를 받았는지 모르겠습니다. 그것은 매우 잘 작동합니다-나는 많은 프로젝트에서 그것을 사용했습니다.
스테판 S.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.