2013-04-26 14 views
16

Mam funkcji, które wykonuje to:Bind Param z tablicy parametrów

function registerUser($firstName, $lastName, $address, $postcode, $email, $password) 
    { 
     $params = array($firstName, $lastName, $address, $postcode, $email, $password); 
     $result = $this->db->bind("INSERT INTO Users VALUES (?, ?, ?, ?, ?, ?)", 'ssssss', $params); 
    } 

który wysyła się do mojej klasy bazy danych, która wykonuje to:

public function bind($query, $type, $params) 
     { 

      $this->query = $query; 
      $stmt = $this->mysqli->prepare($this->query); 
      $stmt->bind_param($type, $param); 
      $stmt->execute; 
     } 

Problem ten nie jest praca.

Co miałem nadzieję zrobić, żeby wziąć listę $params i go wymienić je po $type, tak że zapytanie będzie przypominać:

$stmt->bind_param('ssssss', $firstName, $lastName, $address, $postcode, $email, $password); 

Ale oczywiście zamierzam o tym złym droga.

Czy istnieje sposób na przekształcenie tablicy ... w niezmienioną postać na listę do wydrukowania na etapie zapytania bind_param?

+1

Zapytanie widocznie źle. Wykonaj przed bind_param jeden błąd 'var_dump ($ this-> mysqli->),' aby dowiedzieć się, co się dzieje. – bwoebi

Odpowiedz

24

call_user_func_array()!

call_user_func_array(array($stmt, "bind_param"), array_merge(array($type), $params)); 

powinien wykonać zadanie

UPDATE: trzeba również zmienić tablicę params:

$params = array(&$firstName, &$lastName, &$address, &$postcode, &$email, &$password); 

jak mysqli_stmt::bind_param oczekuje, że druga i następujące parametry przez odniesienie.


EDYCJA: Twoje zapytanie jest nieprawidłowe. Może masz mniej pól, niż masz tam zmienne. Czy:

"INSERT INTO Users (field1, field2, field3, field4, field5, field6) VALUES (?, ?, ?, ?, ?, ?)" 

gdzie wymienić nazwy pól przez poprawnych nazw

+0

Miałeś rację - brakowało pola. Naprawiłem to Jednak przy użyciu call_user_func_array jak wyżej, pojawia się błąd "Ostrzeżenie: array_merge() [function.array-merge]: Argument nr 1 nie jest tablicą Ostrzeżenie: call_user_func_array() oczekuje, że parametr 2 będzie tablicą , null podano " –

+0

@DavidG Użyj, a następnie" array_merge (array (typ $), $ params) '. Ale kiedy twoje '$ params' nie jest ustawione, nie mogę zrobić nic, jak powinno być. – bwoebi

+0

Dziękuję za pomoc :) To prawie działa. Pojawia się błąd: Ostrzeżenie: Parametr 2 do mysqli_stmt :: bind_param() powinien być referencją, wartość podana Postaram się ustalić, co to jest o –

1

najprostszy sposób będzie widocznie przełączających z mysqli do PDO

Pozwoli Ci to zrobić na tak jak chcesz, a nawet bez żadnych dodatkowych funkcji:

function registerUser($firstName, $lastName, $address, $postcode, $email, $password) 
{ 
    $sql = "INSERT INTO Users VALUES (NULL, ?, ?, ?, ?, ?, ?)"; 
    $stmt = $this->db->prepare($sql); 
    $stmt->execute(func_get_args()); 
} 
+2

jego problem polega na tym, że '$ stmt' nie jest obiektem' mysqli_stmt' podobno ... – bwoebi

+0

@ Twój zdrowy rozsądek czy uważasz PDO za lepszy od mysqli? Używam też głównie mysqli, ale nie wiem zbyt wiele na temat PDO. – Aris

+0

@Aris jak widać, PDO wymagają znacznie mniej kodu. Te 2 linie to * wszystko *, czego potrzebujesz. Nie jest wymagana dodatkowa funkcja wiązania. PDO może to zrobić z pudełka –

2

Otrzymujesz błąd "Zadzwoń do członka f unction bind_param() na nieobiektowym "najprawdopodobniej, ponieważ twoje $ this-> mysqli-> prepare napotyka jakiś błąd. (patrz http://php.net/manual/de/mysqli.prepare.php - zwraca FALSE w przypadku błędu, który wydaje się być w tym przypadku)

Po rozwiązać ten problem, spróbuj zamiast rozmowy z $ stmt-> bind_param:

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

Ważne jest, aby pamiętać, że mysqli_stmt_bind_param() wymaga podania parametrów przez odniesienie, więc parametry dla call_user_func_array() muszą być odniesieniami. Przykład wzięty z kontekstu klasy:

function execute(string $query, string $type, array $params) 
{ 
    if (!$stmt = $this->mysqli->prepare($query)) 
     throw new \Exception('Prepare failed: ' . $query . PHP_EOL . $this->mysqli->error); 

    // call stmt->bind_param() with variables to bind passed as a reference 
    call_user_func_array( 
     array($stmt, 'bind_param'), 
     array_merge( 
      array($type), 
      array_map(function(&$item) { return $item; }, $params) 
     ) 
    ); 

    if (!$stmt->execute()) 
     throw new \Exception('Execute failed: ' . PHP_EOL . $stmt->error); 

} 

} 
8

W PHP 5.6 można użyć rozpakowywania argumentów jako alternatywy dla call_user_func_array i często jest 3-4 razy szybszy.

$func = 'foo'; 
$values = array(1, 2); 
call_user_func_array($func, $values); 
//returns 3 

$func(...$values); 
//returns 3 
?> 

Zrobione z here.

więc kod powinien wyglądać mniej więcej tak:

public function bind($query, $type, $params) 
     { 

      $this->query = $query; 
      $stmt = $this->mysqli->prepare($this->query); 
      $stmt->bind_param($type, ...$params); 
      $stmt->execute; 
     } 
Powiązane problemy