9

在我即将结束的一个项目中,我为 PHP 编写并实现了一个对象关系映射解决方案。在怀疑者和梦想家大声喊出“到底是怎么回事?”之前,放松一下——我还没有找到一种方法来使后期的静态绑定起作用——我只是在以尽可能最好的方式解决它。

无论如何,我目前没有使用准备好的语句进行查询,因为我想不出一种方法来将可变数量的参数传递给bind_params()orbind_result()方法。

你问,为什么我需要支持可变数量的参数?因为我的模型的超类(将我的解决方案想象成一个被破解的 PHP ActiveRecord 崇拜者)是定义查询的地方,因此例如 find() 方法不知道它需要绑定多少参数.

现在,我已经考虑过构建一个参数列表并将一个字符串传递给 eval(),但我不太喜欢这种解决方案——我宁愿只实现自己的安全检查并传递语句。

有没有人对如何完成这项工作有任何建议(或成功案例)?如果你能帮我解决第一个问题,也许我们可以解决结果集的绑定问题(如果涉及到确定表结构的初始查询,我怀疑这会更困难,或者至少更耗费资源)。

4

5 回答 5

12

在 PHP 中,您可以使用call_user_func_array. 一个方法的例子是:

call_user_func_array(array(&$stmt, 'bindparams'), $array_of_params);

将调用该函数,并将数组中的每个成员作为其自己的参数传递。

于 2008-08-16T10:58:05.587 回答
2

更现代的动态绑定参数的方法是通过 splat/spread 运算符 ( ...)。

假设:

  • 您有一个非空值数组要绑定到您的查询和
  • 您的数组值在查询的上下文中被适当地处理为字符串类型值,并且
  • 你的输入数组被称为$values

PHP5.6 及更高版本的代码:

$stmt->bind_param(str_repeat('s', count($values)), ...$values);

事实上,bind_param()如果您愿意,可以使用 splat/spread 运算符解压缩所有输入的参数——数据类型字符串只需是数组的第一个元素。

array_unshift($values, str_repeat('s', count($values)));
$stmt->bind_param(...$values);
于 2019-10-13T13:51:01.367 回答
1

您必须确保 $array_of_params 是指向 variables 的链接数组,而不是值本身。应该:

$array_of_params[0] = &$param_string; //link to variable that stores types

进而...

$param_string .= "i";
$user_id_var = $_GET['user_id'];//
$array_of_params[] = &$user_id_var; //link to variable that stores value

否则(如果它是值数组)你会得到:

PHP 警告:mysqli_stmt::bind_param() 的参数 2 应为参考


再举一个例子:

$bind_names[] = implode($types); //putting types of parameters in a string
for ($i = 0; $i < count($params); $i++)
{
   $bind_name = 'bind'.$i; //generate a name for variable bind1, bind2, bind3...
   $$bind_name = $params[$i]; //create a variable with this name and put value in it
   $bind_names[] = & $$bind_name; //put a link to this variable in array
}

和 BOOOOOM:

call_user_func_array( array ($stmt, 'bind_param'), $bind_names); 
于 2011-08-30T09:03:23.973 回答
0

我不允许编辑,但我相信代码

call_user_func_array(array(&$stmt, 'bindparams'), $array_of_params);

$stmt 前面的引用不是必须的。由于$stmt是对象并且bindparams是该对象中的方法,因此不需要引用。它应该是:

call_user_func_array(array($stmt, 'bindparams'), $array_of_params);

有关更多信息,请参阅有关回调函数的 PHP 手册。”

于 2008-09-17T05:45:35.987 回答
0
call_user_func_array(array(&$stmt, 'bindparams'), $array_of_params);

在我的环境中对我不起作用,但这个答案让我走上了正轨。实际起作用的是:

$sitesql = '';
$array_of_params = array();
foreach($_POST['multiselect'] as $value){
    if($sitesql!=''){
        $sitesql .= "OR siteID=? ";
        $array_of_params[0] .= 'i';
        $array_of_params[] = $value;
    }else{
        $sitesql = " siteID=? ";
        $array_of_params[0] .= 'i';
        $array_of_params[] = $value;
    }
}

$stmt = $linki->prepare("SELECT IFNULL(SUM(hours),0) FROM table WHERE ".$sitesql." AND week!='0000-00-00'");
call_user_func_array(array(&$stmt, 'bind_param'), $array_of_params);
$stmt->execute();
于 2010-04-04T20:11:05.623 回答