2009-12-16 126 views
8

請參閱下面的代碼。 我正試圖將一個參數數組綁定到我準備好的語句中。 我一直在網上找東西,可以看到我必須使用call_user_func_array,但無法讓它工作。我得到的錯誤是: 「第一個參數是有望成爲一個有效的回調,‘數組’被賦予」 我可能是錯的,但我假設第一個參數可以是一個數組,或許是此錯誤消息是誤導。我認爲問題在於我的陣列有問題。 任何人都可以看到我做錯了什麼?謝謝。使用call_user_func_array的MySQLI綁定參數

$type = array("s", "s"); 
$param = array("string1","anotherstring"); 

$stmt = $SQLConnection->prepare("INSERT INTO mytable (comp, addl) VALUES (?,?)"); 

$params = array_merge($type, $param); 

call_user_func_array(array(&$stmt, 'bind_param'), $params); 
$SQLConnection->execute(); 
+0

我看到我在第一線的錯誤應該是: $型=陣列(「SS 「); – Columbo 2009-12-16 10:59:49

+0

像這樣的情況下,我確信PDO優於mysqli。 – 2018-01-03 17:51:47

回答

9

我不知道你爲什麼必須使用call_user_func_array,但這是另一個故事。

可能是錯誤的,我眼中唯一的事情是,你正在使用的對象的引用。您正在使用PHP 5 *假設,這是沒有必要的:

call_user_func_array(array($stmt, 'bind_param'), $params); 
+0

感謝弗朗茨,我使用call_user_func_array,因爲要綁定的參數數量各不相同。我正在使用PHP5,但刪除參考staill產生相同的結果。 – Columbo 2009-12-16 11:14:22

+0

然後,這意味着你的對象有什麼問題。看到這個PHP「bug」報告:http://bugs.php.net/bug.php?id=46229。 'var_dump($ stmt)'在那個地方給你什麼? – Franz 2009-12-16 11:19:01

+0

是的,我只是得到布爾(真)而不是聲明。不知道爲什麼要去看看。我想這是給我一個TRUe來說,聲明preperation是成功的。但是我已經在幾個例子中看到了人們正在做我在做的事情。 – Columbo 2009-12-16 11:28:11

16

它必須是這樣的:

//connect 
$mysqli = new mysqli($host, $user, $password, $db_name); 

//prepare 
$stmt = $mysqli->prepare("SELECT * FROM the_table WHERE field1= ? AND Field2= ?"); 

//Binding parameters. Types: s = string, i = integer, d = double, b = blob 
$params= array("ss","string_1","string_2"); 

//now we need to add references 
$tmp = array(); 
foreach($params as $key => $value) $tmp[$key] = &$params[$key]; 
// now us the new array 
call_user_func_array(array($stmt, 'bind_param'), $tmp); 

$stmt->execute(); 

/* Fetch result to array */ 
$res = $stmt->get_result(); 
while($row = $res->fetch_array(MYSQLI_ASSOC)) { 
    $a_data[]=$row; 
} 
print_r($a_data); 

$stmt->close(); 
+0

終於在這個例子的幫助下解決了我的問題。問題在於大多數示例似乎都是對'params array'進行硬編碼,但是我需要根據發佈到我的API來動態生成這些代碼。我不得不建立一個函數,它接受這些值並構建params數組,然後使用'call_user_function_array'。我在這裏把我的解決方案放在我原來的問題上:[如何將逗號分隔...與NOT IN ...](https://stackoverflow.com/questions/47821201/how-to-bind-comma-separated -ids-使用-mysqli的-語句綁定-PARAM換不限於化學stateme?noredirect = 1#comment82605027_47821201)。 – 2017-12-15 20:52:52

0

你爲什麼要打電話call_user_func_array(陣列($聲明,「bind_param '),$ bind_arguments)?因爲$ bind_arguments是一個數組。無論您有多少參數,您都可以擁有一個將語句綁定到其查詢參數的函數。良好的代碼

例...的惡意代碼

<?php 
      # link 
     $dblink = new mysqli('HOSTNAME','USERNAME','PASSWORD','DATABASENAME'); 

      # example data 
     $statement = $dblink->prepare("SELECT * from Person WHERE FirstName = ? AND MiddleName = ? AND LastName = ? and Age = ?"); 
     $recordvalues = ['John', 'H.', 'Smith', 25]; 
     $sqlbindstring = "sssi"; # String, String, String, Integer example 

      # make the references 
     $bind_arguments = []; 
     $bind_arguments[] = $sqlbindstring; 
     foreach ($recordvalues as $recordkey => $recordvalue) 
     { 
      $bind_arguments[] = & $recordvalues[$recordkey]; # bind to array ref, not to the temporary $recordvalue 
     } 

      # query the db 
     call_user_func_array(array($statement, 'bind_param'), $bind_arguments);  # bind arguments 
     $statement->execute(); # run statement 
     $result = $statement->get_result(); # get results 

      # get the results 
     if($result) { 
      while ($row = $result->fetch_assoc()) { 
       print("\n\nMy row is..."); 
       print_r($row); 
      } 
     } 
    ?> 

例...

<?php 

      # Same setup as above.. 

     $statement->prepare("SELECT * from Person WHERE FirstName = ? AND MiddleName = ? AND LastName = ? and Age = ?"); 
     $statement->bind('John', 'H.", 'Smith', 25); 

    ?> 

在第一個例子:你可以傳遞儘可能多或儘可能少的結合是完成,以便bind()可能只在整個應用程序的一行中調用。這比例很好。

在第二個例子:你必須寫一個bind()的聲明中對每個可能組插入爲數據庫中的每一個可能的記錄。這比例很差。

+0

你的答案是對另一個答案的迴應... – 2016-07-04 16:13:15

0

如果你得到一個錯誤,你應該試試這個:

call_user_func_array(array($stmt, 'bind_param'), refValues($params)); 

function refValues($arr){ 
    if (strnatcmp(phpversion(),'5.3') >= 0) { 
     $refs = array(); 
     foreach($arr as $key => $value) 
      $refs[$key] = &$arr[$key]; 
     return $refs; 
    } 
    return $arr; 
} 
1

未能回答這個對我自己的問題,因爲它得到了標記爲重複數據刪除:here。但是,我認爲我的最終解決方案使用了這個問題中的答案,適用於我的用例,可能對某人有所幫助。

我的目標是採取張貼集的ID,並在NOT IN MYSQL語句中使用它們。假設發佈了5個ID的數組。

  1. 數數發佈ID的建立?佔位符NOT IN聲明。使用$params_count = substr(str_repeat(',?', count($array_of_ids)), 1);給出結果:要在SQL語句中使用(?,?,?,?,?)

  2. 使功能,需要ID和iss等。對我來說,他們都是i所以我的功能更簡單。返回數組,看起來像這樣$params= array("iiiii",1,2,3,4,5)其中第一個值是i的集合,隨後的值是ID取決於傳入函數的總ID。

    function build_bind_params($values, $bind_type) { 
        $s = substr(str_repeat($bind_type, count($values)), 0); 
        $bind_array = array(); 
        $bind_array[] = $s; 
        foreach($values as $value) { 
         $bind_array[] = $value; 
        } 
        return $bind_array; 
    } 
    

$params = build_bind_params($array_of_ids, "i");

  • 然後使用foreach ($params as $key => $value) $tmp[$key] = &$params[$key];獲得新創建$params結合正確格式化。

  • 然後使用call_user_func_array(array($stmt , 'bind_param') , $tmp);正確地綁定數組。

  • 然後將其添加到之前call_user_func_array不整合與所述值沿着類型執行$stmt

  • 1
    大多數

    以上的不解決方案()。該解決方案爲我工作:

    /* create a database connection */ 
    $db = new mysqli($host, $user, $password, $db_name); 
    
    /* setup the sql, values, and types */ 
    $sql="SELECT * FROM languages 
         WHERE language_code = ? 
          AND charset = ? 
         ORDER BY native_name"; 
    $values = array($langCode, $charset); 
    $types = "ss"; 
    
    /* pass those variables to the execute() function defined below */ 
    if ($rows = execute($sql, $values, $types)) 
    { 
        return $rows[0]; 
    } 
    
    function execute($sql, $values='', $types='') 
    { 
        /* prepare the sql before binding values and types */ 
        $stmt = $db->prepare($sql); 
    
        /*combine the values and types into $inputArray */ 
        $inputArray[] = &$types; 
        $j = count($values); 
        for($i=0;$i<$j;$i++){ 
        $inputArray[] = &$values[$i]; 
        } 
        /* add the combined values and types to call_user_func_array() for binding */ 
        call_user_func_array(array($stmt, 'bind_param'), $inputArray); 
        $result = $stmt->execute(); 
        return $result; 
    } 
    

    這裏充分描述的引用這個例子是基於: http://big.info/2015/08/php-use-call_user_func_array-for-variable-number-of-parameters-arrays-in-prepared-statements.html