0

There's a number of questions on this that are answered here but I cant find what is wrong with mine.

DB class that uses mysqli which is stored as a property. The prepare, bind and execute are triggered with the magic call methods:

public static function __callStatic($name, $arg)
{
    echo '<pre>';
    var_dump($arg);
    echo '</pre>';
    if($name == 'Prepare'){
        self::$Stmt = self::$mysqli->prepare(implode(', ', $arg));
        $return = self::$Stmt;
    }elseif($name == 'Bind')
        $return = self::$Stmt->bind_param(implode(', ', $arg));
    elseif($name == 'Execute')
        $return = self::$Stmt->execute();
    else
        $return = self::$mysqli->$name(implode(', ', $arg));
    if(!self::GetErr())
        return $return;
}

Also I have a class that generates SQL statements. This is the ouput used in the prepare statement:

INSERT INTO account (UName, FName, LName, Email, Password, RecQuestion, RecAnswer, Admin) VALUES (?, ?, ?, ?, ?, ?, ?, ?) 

Here is the code:

DB::Prepare(SQL::Table('account')->Insert([
    'UName' => '?',
    'FName' => '?',
    'LName' => '?',
    'Email' => '?',
    'Password' => '?',
    'RecQuestion' => '?',
    'RecAnswer' => '?',
    'Admin' => '?'
]));
DB::Bind('sssssssi', $userName, $fName, $lName, $email, $password, $recQ, $recA, $admin);
DB::Execute();

As I can see there are 8 types and 8 values to go with it...

also here is the output of var_dump($arg) for when DB::Bind is called

array(9) {
  [0]=>
  string(8) "sssssssi"
  [1]=>
  string(4) "user"
  [2]=>
  string(5) "first"
  [3]=>
  string(4) "last"
  [4]=>
  string(15) "[email protected]"
  [5]=>
  string(64) "$2a$10$Tw4eOkUYA6SX8WP8XJfKZeFfOM9htVRJyP0d1iYlka0jNCV/qPGzazakT"
  [6]=>
  string(7) "recover"
  [7]=>
  string(64) "$2a$10$LrfK2EdkRi6pPdx1tUtPWe8p24T8ISdQHYhW0N06RjbvCrU4Flqiie4jU"
  [8]=>
  int(1)
}
6
  • 1
    DB::Bind('sssssssi', $userName, $fName, $lName, $email, $password, $recQ, $recA, $admin); there are 9. Do you really need this `'sssssssi'? Commented Aug 9, 2012 at 2:29
  • yes that's how it should be? the first is the 8 types and then the 8 values. php.net/manual/en/mysqli-stmt.bind-param.php Commented Aug 9, 2012 at 2:32
  • last time I checked. 1) $userName, 2) $fName, 3) $lName, 4) $email, 5) $password, 6) $recQ, 7) $recA, 8) $admin wheres the 9th value? Commented Aug 9, 2012 at 2:44
  • -_- look at the documentation. 'sssssssi' is a required paramater for the column types. s=string and i=int; Commented Aug 9, 2012 at 2:46
  • Try removing the quotes from around the question marks. Commented Aug 9, 2012 at 4:26

1 Answer 1

2

implode(', ', $arg) returns a single string so it was only getting one parameter. The proper way to go about this is using call_user_func_array();

However its not as obvious as it may seem. bind_param() expects the arguements to be passed by reference and not by value. __callStatic($name, $arg) has an array of values and not references so a local copy with references to these values is needed.

Solution:

elseif($name == 'Bind'){
    foreach($arg as &$v)
        $Arg[] = &$v;
    $return = call_user_func_array(array(self::$Stmt, 'bind_param'), $Arg);
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.