php 将参数与参数数组绑定

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16236395/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 10:45:05  来源:igfitidea点击:

Bind Param with array of parameters

phpmysqlibind

提问by David G

I have a function that does this:

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

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

Which sends off to my database class, which does this:

它发送到我的数据库类,它执行以下操作:

public function bind($query, $type, $params)
{
    $this->query = $query;
    $stmt = $this->mysqli->prepare($this->query);
    $stmt->bind_param($type, $param);
    $stmt->execute;
}

The problem is this doesn't work.

问题是这行不通。

What I was hoping to do, was to take the $paramslist and have it list them after the $type, so that the query would resemble:

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

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

But obviously I'm going about it the wrong way.

但显然我的做法是错误的。

is there a way to make the array...transform as it were, into a list to be printed out at the bind_paramquery stage?

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

回答by bwoebi

call_user_func_array"Call a callback with an array of parameters"

call_user_func_array"使用参数数组调用回调"

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

should do the job

应该做这份工作

UPDATE: you have also to change your params array:

更新:您还必须更改 params 数组:

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

as mysqli_stmt::bind_paramexpects the second and the following parameters by reference.

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



EDIT: Your query seems to be wrong. Maybe you have less fields than you have variables there. Do:

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

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

where you replace the name of the fields by the correct names

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

回答by Havardox

As of PHP 5.6 you can utilize argument unpacking as an alternative to call_user_func_array, and is often 3 to 4 times faster.

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

Taken from here.

取自这里

So your code should look something like this:

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

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

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

回答by phry

You get your error "Call to a member function bind_param() on a non-object" most likely, because your $this->mysqli->prepare encounters some kind of error. (see http://php.net/manual/de/mysqli.prepare.php- it returns FALSE on error, which seems to be the case here)

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

After you have resolved that problem, try this instead of your call of $stmt->bind_param:

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

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

回答by Your Common Sense

The easiestway would be apparently switching from mysqli to PDO

最简单的方法是显然从切换到mysqli的PDO

It will let you to do it the way you want, and even without any additional functions:

它可以让您按照自己的方式进行操作,甚至无需任何附加功能:

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

回答by Danijel

It is important to note that mysqli_stmt_bind_param()requires parameters to be passed by reference, so the parameters for call_user_func_array()must be a reference. An example taken from class context:

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

}

}

回答by Mart

Today, I did some research myself in order to create a shorter method of using the prepare statement. The answer @bwoebi is very helpful but not working for an unknown amount of parameters so this is an addition to his answer.

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

For instance:

例如:

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

using this thread: PHP: variable-length argument list by reference?

使用这个线程: PHP:可变长度参数列表引用?

I managed to accomplish to pass on an unknown amount of parameters to the bind function inside the class. i then call upon the bind param function using call_user_func_array(...) with an array merge of the $type variable... (must be placed inside array for the merge)

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

Now i can call upon this function with $email and $password now being references:

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

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