복붙노트

PHP에서 동적으로 mysqli bind_param 인수를 바인딩하는 방법?

PHP

PHP에서 동적으로 mysqli bind_param 인수를 바인딩하는 방법?

나는 SQL 쿼리를 위해 prepared statement와 bound statement를 사용하는 법을 배웠다. 나는 지금까지 이걸 가지고왔다. 괜찮 았지만, 여러개의 매개 변수가 필요할 때 또는 전혀 매개 변수가 필요하지 않을 때 동적이지 않다.

public function get_result($sql,$parameter)
    {
        # create a prepared statement
    $stmt = $this->mysqli->prepare($sql);

        # bind parameters for markers
    # but this is not dynamic enough...
        $stmt->bind_param("s", $parameter);

        # execute query 
        $stmt->execute();

    # these lines of code below return one dimentional array, similar to mysqli::fetch_assoc()
        $meta = $stmt->result_metadata(); 

        while ($field = $meta->fetch_field()) { 
            $var = $field->name; 
            $$var = null; 
            $parameters[$field->name] = &$$var; 
        }

        call_user_func_array(array($stmt, 'bind_result'), $parameters); 

        while($stmt->fetch()) 
        { 
            return $parameters;
            //print_r($parameters);      
        }


        # close statement
        $stmt->close();
    }

이것은 객체 클래스를 호출하는 방법입니다.

$mysqli = new database(DB_HOST,DB_USER,DB_PASS,DB_NAME);
$output = new search($mysqli);

가끔은 매개 변수를 전달할 필요가 없습니다.

$sql = "
SELECT *
FROM root_contacts_cfm
";

print_r($output->get_result($sql));

때로는 단 하나의 매개 변수 만 필요합니다.

$sql = "
SELECT *
FROM root_contacts_cfm
WHERE root_contacts_cfm.cnt_id = ?
ORDER BY cnt_id DESC
";

print_r($output->get_result($sql,'1'));

때로는 하나 이상의 매개 변수 만 필요합니다.

$sql = "
SELECT *
FROM root_contacts_cfm
WHERE root_contacts_cfm.cnt_id = ?
AND root_contacts_cfm.cnt_firstname = ?
ORDER BY cnt_id DESC
";

print_r($output->get_result($sql,'1','Tk'));

그래서 저는이 라인이 위의 역동적 인 작업에 충분히 동적이지 않다고 믿습니다.

$stmt->bind_param("s", $parameter);

역동적으로 bind_param을 빌드하려면 온라인상의 다른 게시물에서 이것을 발견했습니다.

call_user_func_array(array(&$stmt, 'bind_params'), $array_of_params);

그리고 php.net에서 일부 코드를 수정하려고했지만 아무데도 갈 수 없어,

if (strnatcmp(phpversion(),'5.3') >= 0) //Reference is required for PHP 5.3+ 
    { 
        $refs = array(); 
        foreach($arr as $key => $value) 
            $array_of_param[$key] = &$arr[$key]; 

       call_user_func_array(array(&$stmt, 'bind_params'), $array_of_params);

     }

왜? 내가 어떻게 만들 수있는 아이디어?

아니면 더 나은 해결책이 있을까요?

해결법

  1. ==============================

    1.mysqli에 대한 해답을 찾았습니다.

    mysqli에 대한 해답을 찾았습니다.

    public function get_result($sql,$types = null,$params = null)
        {
            # create a prepared statement
            $stmt = $this->mysqli->prepare($sql);
    
            # bind parameters for markers
            # but this is not dynamic enough...
            //$stmt->bind_param("s", $parameter);
    
            if($types&&$params)
            {
                $bind_names[] = $types;
                for ($i=0; $i<count($params);$i++) 
                {
                    $bind_name = 'bind' . $i;
                    $$bind_name = $params[$i];
                    $bind_names[] = &$$bind_name;
                }
                $return = call_user_func_array(array($stmt,'bind_param'),$bind_names);
            }
    
            # execute query 
            $stmt->execute();
    
            # these lines of code below return one dimentional array, similar to mysqli::fetch_assoc()
            $meta = $stmt->result_metadata(); 
    
            while ($field = $meta->fetch_field()) { 
                $var = $field->name; 
                $$var = null; 
                $parameters[$field->name] = &$$var; 
            }
    
            call_user_func_array(array($stmt, 'bind_result'), $parameters); 
    
            while($stmt->fetch()) 
            { 
                return $parameters;
                //print_r($parameters);      
            }
    
    
            # the commented lines below will return values but not arrays
            # bind result variables
            //$stmt->bind_result($id); 
    
            # fetch value
            //$stmt->fetch(); 
    
            # return the value
            //return $id; 
    
            # close statement
            $stmt->close();
        }
    

    그때:

    $mysqli = new database(DB_HOST,DB_USER,DB_PASS,DB_NAME);
    $output = new search($mysqli);
    
    $sql = "
    SELECT *
    FROM root_contacts_cfm
    ORDER BY cnt_id DESC
    ";
    print_r($output->get_result($sql));
    
    $sql = "
    SELECT *
    FROM root_contacts_cfm
    WHERE root_contacts_cfm.cnt_id = ?
    ORDER BY cnt_id DESC
    ";
    
    print_r($output->get_result($sql,'s',array('1')));
    
    $sql = "
    SELECT *
    FROM root_contacts_cfm
    WHERE root_contacts_cfm.cnt_id = ?
    AND root_contacts_cfm.cnt_firstname = ?
    ORDER BY cnt_id DESC
    ";
    
    print_r($output->get_result($sql, 'ss',array('1','Tk')));
    

    mysqli는 이렇게 절름발이입니다. PDO로 마이그레이션해야한다고 생각합니다!

  2. ==============================

    2.PHP 5.6을 사용하면 연산자 (... $ var)를 풀고 bind_result () 메소드의 get_result () 메소드를 사용하여 쉽게이 작업을 수행 할 수 있습니다.

    PHP 5.6을 사용하면 연산자 (... $ var)를 풀고 bind_result () 메소드의 get_result () 메소드를 사용하여 쉽게이 작업을 수행 할 수 있습니다.

    public function get_result($sql,$types = null,$params = null) {
        $stmt = $this->mysqli->prepare($sql);
        $stmt->bind_param($types, ...$params);
    
        if(!$stmt->execute()) return false;
        return $stmt->get_result();
    
    }
    

    예:

    $mysqli = new database(DB_HOST,DB_USER,DB_PASS,DB_NAME);
    $output = new search($mysqli);
    
    
    $sql = "SELECT * FROM root_contacts_cfm WHERE root_contacts_cfm.cnt_id = ?
            AND root_contacts_cfm.cnt_firstname = ?
            ORDER BY cnt_id DESC";
    
    $res = $output->get_result($sql, 'ss',array('1','Tk'));
    while($row = res->fetch_assoc()){
       echo $row['fieldName'] .'<br>';
    }
    
  3. ==============================

    3.이 답변은별로 도움이되지 않지만 mysqli에서 PDO로 전환하는 것을 진지하게 고려해야합니다.

    이 답변은별로 도움이되지 않지만 mysqli에서 PDO로 전환하는 것을 진지하게 고려해야합니다.

    이것의 주된 이유는 PDO가 mysqli에서 내장 함수를 사용하여 수행하려는 작업을 수행하기 때문입니다. 수동 param 바인딩 외에도 execute 메소드는 대신 인수 배열을 사용할 수 있습니다.

    PDO는 쉽게 확장 할 수 있으며, 준비 실행 댄스를하는 대신 모든 것을 가져 오는 편리한 방법을 추가하는 것은 매우 쉽습니다.

  4. ==============================

    4.나는 좋은 mysqli 클래스를 발견했다, 그것은 동적 인 매개 변수를 처리 할 수 ​​있고, 사용하기 쉽다.

    나는 좋은 mysqli 클래스를 발견했다, 그것은 동적 인 매개 변수를 처리 할 수 ​​있고, 사용하기 쉽다.

    https://github.com/ajillion/PHP-MySQLi-Database-Class

    동적으로 쿼리를 작성하는 방법을 소스 코드에서 참조 할 수 있습니다.

    https://github.com/ajillion/PHP-MySQLi-Database-Class/blob/master/MysqliDb.php

  5. ==============================

    5.PHP 5.6 이상 :

    PHP 5.6 이상 :

    $stmt->bind_param(str_repeat("s", count($data)), ...$data);
    

    PHP 5.5 이하를 사용하면 다음과 같은 기능을 기대할 수 있습니다.

    call_user_func_array(
        array($stmt, "bind_param"),
        array_merge(array(str_repeat("s", count($data))), $data));
    

    ...하지만 mysqli_stmt :: bind_param은 매개 변수가 참조 인 반면 값 목록을 전달합니다.

    원래 배열에 대한 참조 배열을 먼저 작성하여이 문제를 해결할 수 있습니다 (추악한 해결 방법 임).

    $references_to_data = array();
    foreach ($data as &$reference) { $references_to_data[] = &$reference; }
    unset($reference);
    call_user_func_array(
        array($stmt, "bind_param"),
        array_merge(array(str_repeat("s", count($data))), $references_to_data));
    
  6. from https://stackoverflow.com/questions/5100046/how-to-bind-mysqli-bind-param-arguments-dynamically-in-php by cc-by-sa and MIT license