21

我有一个功能可以做到这一点:

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查询阶段打印出来的列表?

4

7 回答 7

28

call_user_func_array "调用带有参数数组的回调"

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

应该做的工作

更新:您还必须更改您的参数数组:

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

正如mysqli_stmt::bind_param预期的第二个和以下参数通过引用。


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

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

用正确的名称替换字段的名称

于 2013-04-26T12:27:01.353 回答
13

从 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
?>

取自这里

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

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

            $this->query = $query;
            $stmt = $this->mysqli->prepare($this->query);
            $stmt->bind_param($type, ...$params);
            $stmt->execute;
        }
于 2017-03-31T07:27:16.500 回答
2

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

在你解决了这个问题之后,试试这个而不是你调用 $stmt->bind_param:

call_user_func_array(array($stmt, 'bind_param'), array_merge($type, $params));
于 2013-04-26T12:33:44.353 回答
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());
}
于 2013-04-26T12:28:31.917 回答
0

需要注意的是,mysqli_stmt_bind_param()要求参数通过引用传递,所以参数forcall_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 );

}

}
于 2016-06-19T23:43:00.667 回答
0

今天,我自己做了一些研究,以创建一个使用准备语句的更短的方法。@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?

我设法将未知数量的参数传递给类内的绑定函数。然后我使用带有 $type 变量的数组合并的 call_user_func_array(...) 调用绑定参数函数...(必须放在数组内进行合并)

现在我可以使用 $email 和 $password 现在作为引用来调用此函数:

$myClass->bind($query, "ss", $email, $password);
于 2018-07-16T13:11:18.237 回答
-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);
}
于 2021-02-03T10:37:14.377 回答