Saya sedang menulis skrip yang pada asasnya memuatkan data daripada API ke dalam pangkalan data MySQL tempatan. Nilai ini berubah berdasarkan apa yang dikembalikan oleh API.
Setakat ini, semuanya berfungsi dengan baik sehingga saya cuba memasukkan baris ke dalam pangkalan data MySQL. Secara khusus, saya tahu saya sepatutnya menggunakan pernyataan yang disediakan, tetapi saya menghadapi masalah apabila saya cuba mengikat pembolehubah kepada pernyataan yang disediakan. Apabila saya cuba menjalankan kod berikut saya dapat:
PHP Warning: mysqli_stmt::bind_param(): Number of elements in type definition string doesn't match number of bind variables in /opt/awn2sql/functions.php on line 212
Ini adalah kod yang dimaksudkan:
$readingValues = array_values($read); //array of just the values in the original array array_push($readingValues, $devicemac); //add the MAC address of the device that recorded the reading to the array $columns = implode(", ",$readingTypes); //create a string of column names to build the SQL query $valuesCount = count($readingValues); //get a count of the values to fill an array with placeholders $stmt_placeholders = implode(',',array_fill(0,$valuesCount,'?')); //fill an array with placeholders (i.e. ?,?,?) - see above $stmt_param = null; //$stmt_param will hold the type definitions string for binding the foreach ($readingValues as $param) { //iterate through each value in the $readingValues array, get the type, and add it to the type definitions string if (gettype($param) == 'integer') { $stmt_param = $stmt_param.'i'; } else if (gettype($param) == 'double') { $stmt_param = $stmt_param.'d'; } else if (gettype($param) == 'string') { $stmt_param = $stmt_param.'s'; } else if (gettype($param) == 'blob') { $stmt_param = $stmt_param.'b'; } else { echo "Invalid data type!"; } } $val_insert_query = "INSERT INTO ".$config['mysql_db'].".readings (".$columns.") VALUES (".$stmt_placeholders.");"; //Template for the query $stmt=$mysqli->prepare($val_insert_query); //Prepares the template for the query for binding, prepared statement becomes $stmt echo ($stmt_param." (".strlen($stmt_param).")\n"); //for debugging, echo the type definiton string and get its length (which should match the number of values) echo (count($readingValues)); //count the number of values, which should match the number of elements in the type defintion string $stmt->bind_param($stmt_param, $readingValues); //Binding $stmt->execute(); //execute the statement
Saya dengan bebas mengakui bahawa saya agak baru dalam hal ini, jadi saya terbuka kepada sebarang cadangan tentang cara melakukannya dengan lebih baik. Untuk nilainya, tidak pernah ada input pengguna langsung, jadi saya agak tidak mengambil berat tentang isu keselamatan, jika itu ada kaitan dengan cara terbaik untuk menyelesaikan masalah ini.
Terima kasih terlebih dahulu!
bind_param()
Sebenarnya menerima argumen berubah, bukan argumen tatasusunan. Tetapi PHP moden mempunyai sintaks untuk menukar tatasusunan kepada berbilang argumen skalar:Ini bersamaan dengan menghantar elemen tatasusunan sebagai hujah berasingan:
Tetapi janggal jika anda tidak tahu berapa banyak elemen yang terdapat dalam array.
FYI, saya lebih suka menggunakan PDO berbanding mysqli. Anda tidak perlu mengikat apa-apa, hanya hantar tatasusunan nilai sebagai hujah kepada
execute()
:Saya dapati PDO lebih mudah. Sebab untuk menggunakan mysqli adalah jika anda mempunyai banyak kod warisan dari pertengahan 2000-an yang memerlukan tweaker. Jika anda baru bermula, tiada kod warisan. Oleh itu, anda juga boleh menggunakan PDO terlebih dahulu.
Terdapat tutorial PDO yang bagus: https://phpdelusions.net/pdo/