2009-12-09 4 views
2

최근에 나는 잘 작동하는 데 사용되는 lib에 오류가 발생하여 어디 있는지 파악할 수 있으면 망할 것입니다.Mysqli 추상화 준비 문에서 배열 가져 오기

코드 샘플은 아래에 있으며, 그 안에 디버그 내용에 대해 사과드립니다. 그러나 작동 시키려고합니다.

문제는 $ temp가 올바른 키 (열 이름)를 가진 배열이지만 모든 값이 NULL이라는 점입니다.

나는 문제가

call_user_func_array(array($query, 'bind_result'), $params); 

비트에있다,하지만 정말 주위에 내 머리를 정리하지 수 있다고 생각합니다.

public function fetchRows(){ 
    error_reporting(E_ALL+E_NOTICE); 
    $args = func_get_args(); 
    $sql = array_shift($args); 
    traceVar($sql, "Query"); 
    $colTypes = array_shift($args); 
    if (!$query = $this->prepare($sql, $colTypes)) { 
     die('Please check your sql statement : unable to prepare'); 
    } 
    if (count($args)){ 
     traceVar($args,'Binding params with'); 
     call_user_func_array(array($query,'bindParam'), $args); 
    } 

    $query->execute(); 

    $meta = $query->result_metadata(); 
    while ($field = $meta->fetch_field()) { 
     $params[] = &$row[$field->name]; 
    } 
    traceVar($params,'Binding results with'); 
    call_user_func_array(array($query, 'bind_result'), $params); 

    while ($query->fetch()) { 
     traceVar($row,'After fetch'); 
     $temp = array(); 
     foreach($row as $key => $val) { 
      $temp[$key] = $val; 
     } 
     $result[] = $temp; 
    } 

    $meta->free(); 
    $query->close(); 
    //self::close_db_conn(); 
    return $result; 
} 

답변

3

제공 한 코드가 저에게 적합합니다. 만약 방법 인수로 배열의 각 요소를 구비 한 것처럼

call_user_func_array(...) 기능은 주어진 어레이와 $query 객체에 bindParambind_result 또는 메소드를 호출한다.

아래 코드를 사용하면 문제가있는 SQL 문을 검사 할 수 있습니다. 원래 코드는 추상화 계층의 명령문 클래스에 따라 다르므로 완전히 테스트 할 수 있도록 약간 다시 작성했습니다.

<?php 

$db_host = 'localhost'; 
$db_user = 'username'; 
$db_pass = 'password'; 
$db_name = 'database'; 

$mysqli = new mysqli($db_host, $db_user, $db_pass, $db_name); 

print_r(fetchRows('SELECT something from some_table WHERE some_id = ?', 'i', 1)); 

function traceVar($a, $b) { 
    print_r(array($b => $a)); 
} 

function fetchRows(){ 
     error_reporting(E_ALL+E_NOTICE); 
     $args = func_get_args(); 
     $sql = array_shift($args); 
     traceVar($sql, "Query"); 

     // Keep the column types for bind_param. 
     // $colTypes = array_shift($args); 

     // Column types were originally passed here as a second 
     // argument, and stored in the statement object, I suppose. 
     if (!$query = $GLOBALS['mysqli']->prepare($sql)){ //, $colTypes)) { 
       die('Please check your sql statement : unable to prepare'); 
     } 
     if (count($args)){ 
       traceVar($args,'Binding params with'); 

       // Just a quick hack to pass references in order to 
       // avoid errors. 
       foreach ($args as &$v) { 
        $v = &$v; 
       } 

       // Replace the bindParam function of the original 
       // abstraction layer. 
       call_user_func_array(array($query,'bind_param'), $args); //'bindParam'), $args); 
     } 

     $query->execute(); 

     $meta = $query->result_metadata(); 
     while ($field = $meta->fetch_field()) { 
       $params[] = &$row[$field->name]; 
     } 
     traceVar($params,'Binding results with'); 
     call_user_func_array(array($query, 'bind_result'), $params); 

     while ($query->fetch()) { 
       traceVar($row,'After fetch'); 
       $temp = array(); 
       foreach($row as $key => $val) { 
         $temp[$key] = $val; 
       } 
       $result[] = $temp; 
     } 

     $meta->free(); 
     $query->close(); 
     //self::close_db_conn(); 
     return $result; 
} 
+0

http://paste2.org/p/554177과 함께 시도해 보니 매력처럼 작동합니다. 내 원본 코드가 어디에서 고장 났는지 궁금합니다. – Madness

+0

변경 사항을 구현할 때 실수를해야합니다. 함수를 http://paste2.org/p/554194로 다시 작성한 다음 http://paste2.org/p/554192를 실행하면 여전히 "Array ([0] => 배열 ([ID] => [사용자 이름] => [암호] => [이름] => [전자 메일] => [액세스 레벨] => [IsTemp] =>)) " – Madness

+0

모든 사용, 나는 또한 여기 클래스에서 다른 비트를 배치 http://paste2.org/p/554201 – Madness

2

우리가 처음에 서버를 선택할 수 있다면 PHP 용 PHP-mysql 모듈 대신 php-mysqlnd 모듈을 사용할 수 있습니다. 나에게 간단 보인다

public function fetchRows(){ 
    ... 
    $query->execute(); 

    $res = $query->get_result(); 
    while (($row = $res->fetch_assoc())) 
     $result[] = $row; 
    return $result; 
    } 
} 

: (와 "mysqlnd"검색 "은 phpinfo()"아니면 이미 그것을 사용하는 당신의 일부는 실행).

+0

나는이 새로운 지식으로 얼마나 많은 질문에 답할 것인가? 대략적인 추정은 괜찮을 것입니다. –

+1

두 명. 과거에는 이러한 솔루션 중 몇 가지를 검색하여 작동 할 수있는 get_result()가 있음을 알지 못했기 때문입니다. 따라서 향후 사용자 참조를 위해 추가하십시오. –

+0

2 명이 적당합니다. 그 문제에 관해 질문 한 수천 가지 질문에 모두 답할 것입니다. –

관련 문제