0

So currently I got this code for preparing queries which works but its inefficient, and might require expansion if the queries become bigger. And there are more pieces of code like this. One example of these pieces of codes goes as follows.

//This function is called when preparing statements to prevent sql-injections(1)
//It binds the variables to the prepared statements based on an array.
//$stmt is the prepared statement. $params is an array with the input data.
public function bind($stmt, $params){
    x = count($params);
    $type = $this->getType($params); //simply obtains the types of the params(2)
    if($x == 1){
        $stmt->bind_param($type, $params[0]);
    }elseif($x == 2){
        stmt->bind_param($type, $params[0], $params[1]);
    }elseif($x == 3){
        $stmt->bind_param($type, $params[0], $params[1], $params[2]);
    }else{
        echo "Too much params";      //error if there are more than 3 params.
    }
    return $stmt;
}

Referenced links from code for extra information, not that it really matters since its just an example.
(1) = How can I prevent SQL injection in PHP?
(2) = http://www.php.net/manual/en/mysqli-stmt.bind-param.php

So as you can see this will return an error if $params contains more than 3 items. So I have been trying to fix this in a more efficient way, because adding more elseif statements is not efficient. I tried all kinds of things with loops, but no good or working results. This problem does not only occur for just this bind_param example, but to other functions as well.

So I would like an easy efficient solution to add an amount of variables to a function-call based on the amount of array items which can be applied to more than just this example.

Community
  • 1
  • 1
kpp
  • 800
  • 2
  • 11
  • 27
  • 2
    You are looking for [`call_user_func_array`](http://www.php.net/manual/en/function.call-user-func-array.php): `call_user_func_array([$stmt, 'bind_param'], $params);`. – Jon May 09 '14 at 13:18
  • Ive come across it but all my attempts to implement it failed so could you give an example on how to do it on my example. – kpp May 09 '14 at 13:19
  • 1
    Also, if you did come across it and tried to use it, **why didn't you say so in the question?** Guessing isn't fun. At least in this case. – Jon May 09 '14 at 13:21

2 Answers2

0

I've created my own function that allows 'unlimited' amount of values, checks the amount if it's correct and creates a string of types.

This function, however, is a tad different, as it asks for the querystring and an array of objects to bind (yours requires a statement).

function CreateStatement($query, $objects) {
    $questionMarks = substr_count($query, '?');
    if ($questionMarks != count($objects))
        $this->ThrowError('Trying to create statement with invalid data', array(
            'Query' => $query,
            'Objects' => $objects 
        ));


    $statement = $this->prepare($query);

    if (count($objects) != 0) {
        $fields = array();
        $out = array();

        $field_notation = '';
        foreach ($objects as $key => $value) {
            if (is_string($value)) $field_notation .= 's';
            elseif (is_float($value)) $field_notation .= 'd';
            elseif (is_int($value)) $field_notation .= 'i';
            elseif ($value instanceof DateTime) {
                $field_notation .= 's';
                $objects[$key] = $value->format(DateTime::ISO8601);
            }
            else $field_notation .= 'b';
        }

        $fields[] = $field_notation;
        foreach ($objects as &$value) {
            $fields[] = &$value;
        }

        call_user_func_array(array($statement, 'bind_param'), $fields);
    }
    return $statement;
}
Diamondo25
  • 769
  • 1
  • 8
  • 21
-1
public function bind($stmt, $params){
  return call_user_func_array(array($stmt, 'bind_param'), $params);
}

http://php.net/call_user_func_array

Duroth
  • 6,315
  • 2
  • 19
  • 23
  • If you're working with `mysql`, read the notes about references and binding params http://www.php.net/manual/en/mysqli-stmt.bind-param.php – Oscar M. May 09 '14 at 15:42
  • @Oscar M.: You're right, ofcourse. `PDOStatement::bindParam()` has functionality that not everyone expects, or even wants. I simply made the assumption that the goal was to bind values, rather than parameters. In which case, `PDOStatement::bindParam()` would be the better option. http://nl1.php.net/manual/en/pdostatement.bindvalue.php – Duroth May 12 '14 at 08:08