Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Problemy z wiązaniem implodowanej tablicy do przygotowanej instrukcji mysql

Pozwól, że oszczędzę ci trochę kłopotów i powiem, że to, co próbujesz zrobić, i tak nie zadziała. Przywiązujesz tylko jeden parametr do swojej IN() wywołanie funkcji. myślisz przekazujesz listę oddzieloną przecinkami, ale w rzeczywistości przekazujesz tylko ciąg oddzielony przecinkami, który jest traktowany jako jedna wartość . Oznacza to, że będziesz szukać jednego rekordu z wartością „'[email protected] ', '[email protected] „” zamiast rekordów pasujących do „[email protected] „ lub „przykł[email protected] ".

Aby rozwiązać ten problem, musisz:

  1. Dynamicznie generuj ciąg typów
  2. Użyj call_user_func_array() do powiązania parametrów

Możesz wygenerować łańcuch typów w następujący sposób:

$types = str_repeat('s', count($selected));

Wszystko to tworzy ciąg s to tyle znaków, ile jest elementów w tablicy.

Następnie powiązałbyś swoje parametry za pomocą call_user_func_array() w ten sposób (zauważ, że ponownie wstawiłem nawias dla IN() funkcja):

if ($stmt = $mysqli->prepare("DELETE FROM email_addresses WHERE email_addresses IN (?)")) {
    call_user_func_array(array($stmt, "bind_param"), array_merge($types, $selected));

Ale jeśli spróbujesz tego, otrzymasz błąd dotyczący mysqli_stmt::bind_param() oczekiwanie, że parametr drugi zostanie przekazany przez odwołanie:

To trochę irytujące, ale dość łatwe do obejścia. Aby obejść ten problem, możesz użyć następującej funkcji:

function refValues($arr){ 
    $refs = array(); 
    foreach($arr as $key => $value) 
        $refs[$key] = &$arr[$key]; 
    return $refs; 
} 

Po prostu tworzy tablicę wartości, które są odniesieniami do wartości w $selected szyk. To wystarczy, aby mysqli_stmt::bind_param() szczęśliwy:

if ($stmt = $mysqli->prepare("DELETE FROM email_addresses WHERE email_addresses IN (?)")) {
    call_user_func_array(array($stmt, "bind_param"), array_merge($types, refValues($selected)));

Edytuj

Od PHP 5.6 możesz teraz używać ... operatora, aby to jeszcze uprościć:

$stmt->bind_param($types, ...$selected);



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Czy `mysqlcheck` może pomóc mi rozwiązać problemy z bazą danych bez uszkadzania mojej bazy danych?

  2. BŁĄD 1067 (42000):Nieprawidłowa wartość domyślna dla „created_at”

  3. Podczas importowania pliku mysqldump BŁĄD 1064 (42000) w pobliżu „■/” w wierszu 1

  4. Czy PDO rowCount() po zapytaniu UPDATE może pokazać różnicę między brakiem zmian a nieistniejącym wierszem?

  5. Poprzedzenie * (gwiazdką) przed wyszukiwaniem pełnotekstowym w MySQL