使用参数数组绑定Param

时间:2013-04-26 12:24:03

标签: php mysqli bind

我有一个执行此操作的功能:

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);
    }

发送到我的数据库类,执行此操作:

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

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

问题是这不起作用。

我希望做的是获取$params列表并将其列在$type之后,以便查询类似于:

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

但显然我的方式错了。

有没有办法让数组......按原样转换成要在bind_param查询阶段打印出来的列表?

7 个答案:

答案 0 :(得分:26)

call_user_func_array()

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

应该做的工作

更新 :您还需要更改params数组:

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

因为mysqli_stmt::bind_param需要引用第二个和以下参数。


编辑:您的查询似乎有误。也许你的字段少于那里的变量。做:

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

您可以使用正确的名称替换字段名称

答案 1 :(得分:10)

从PHP 5.6开始,您可以使用参数解包作为call_user_func_array的替代方法,并且通常快3到4倍。

<?php
function foo ($a, $b) {
     return $a + $b;
}

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

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

取自here

所以你的代码应该是这样的:

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

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

答案 2 :(得分:2)

你得到错误“调用非对象上的成员函数bind_param()”很可能,因为你的$ this-&gt; mysqli-&gt; prepare会遇到某种错误。 (参见http://php.net/manual/de/mysqli.prepare.php - 它在出错时返回FALSE,这似乎就是这种情况)

解决了这个问题后,请尝试此操作,而不是调用$ stmt-&gt; bind_param:

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

答案 3 :(得分:1)

最简单的方式显然会从mysqli切换到PDO

它会让你按照自己的方式去做,甚至没有任何其他功能:

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

答案 4 :(得分:1)

今天,我自己进行了一些研究,以便创建一种使用prepare语句的更短方法。答案@bwoebi非常有帮助,但不适用于未知数量的参数,因此这是他的答案的补充。

例如:

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

        $this->query = $query;
        $stmt = $this->mysqli->prepare($this->query);
        call_user_func_array(array($stmt, "bind_param"), array_merge([$type], $params));
        $stmt->execute();
    }

使用此线程: PHP: variable-length argument list by reference?

我设法完成将未知数量的参数传递给类内的bind函数。 然后我使用带有$ type变量的数组合并的call_user_func_array(...)调用bind param函数...(必须放置在合并数组中)

现在我可以使用$ email和$ password调用此函数了:

$myClass->bind($query, "ss", $email, $password);

答案 5 :(得分:0)

请务必注意mysqli_stmt_bind_param()要求参数通过引用传递,因此call_user_func_array()的参数必须是参考。从类上下文中获取的示例:

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 );

}

}

答案 6 :(得分:-2)

不漂亮,但那是我用的。

function _BindParam(&$stmt, &$values){
    $types="";
    foreach($values as $val){
      if(is_string($val)){$types.="s";continue;}
      if(is_int($val)){$types.="i";continue;}
      if(is_float($val) || is_double($val)){$types.="d";continue;}
      throw new Exception('Invalid value type');
    }
   $stmt->bind_param($types,...$values);
}