복붙노트

정의되지 않은 메소드 호출 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. ==============================

    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. ==============================

    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. ==============================

    3.

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

    (Debian / Ubuntu 기반) 서버에 새로운 패키지를 설치할 수 있으면, 드라이버를 설치하십시오 :

    sudo apt-get install php5-mysqlnd
    

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

    sudo /etc/init.d/apache2 restart
    
  4. ==============================

    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. ==============================

    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. ==============================

    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. ==============================

    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. ==============================

    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. ==============================

    9.

    mysqlnd 확장 기능이 이미 활성화 된 상태에서 PHP 7.0과 동일한 오류가 발생했습니다.

    해결책은 나를위한 것이 었습니다 (이 페이지 덕분에) mysqli 확장을 선택 해제하고 대신 nd_mysqli를 선택했습니다.

    NB - cPanel의 확장 프로그램 선택기에 액세스 할 수 있습니다. (Select PHP Version 옵션을 통해 광산에 액세스합니다.)

  10. from https://stackoverflow.com/questions/8321096/call-to-undefined-method-mysqli-stmtget-result by cc-by-sa and MIT lisence