在我即将结束的项目中,我已经为PHP编写并实现了一个对象关系映射解决方案。在怀疑者和梦想家喊出“怎么样?”之前,放松一下 - 我还没有办法让后期的静态绑定工作 - 我只是以最好的方式解决它。
无论如何,我目前没有使用预准备语句进行查询,因为我无法想出一种方法来将可变数量的参数传递给bind_params()
或bind_result()
方法。
为什么我需要支持可变数量的参数?因为我的模型的超类(将我的解决方案想象为hack-up-PHP ActiveRecord wannabe)是定义查询的地方,所以find()方法例如不知道绑定需要多少参数
现在,我已经考虑过构建一个参数列表并将字符串传递给eval(),但我不太喜欢这个解决方案 - 我宁愿只实现自己的安全检查并传递语句
有没有人有关于如何完成这项工作的任何建议(或成功案例)?如果你可以帮我解决第一个问题,也许我们可以解决绑定结果集(我怀疑会更困难,或者如果涉及初始查询以确定表结构,则至少需要更多资源)。
答案 0 :(得分:13)
在PHP中,您可以使用call_user_func_array
将可变数量的参数传递给函数或方法。方法的一个例子是:
call_user_func_array(array(&$stmt, 'bindparams'), $array_of_params);
将调用该函数,并将数组中的每个成员作为自己的参数传递。
答案 1 :(得分:2)
您必须确保$ array_of_params是链接到变量的数组,而不是值本身。应该是:
$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警告:参数2到mysqli_stmt :: bind_param()应该是参考
又一个例子:
$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);
答案 2 :(得分:1)
我不允许编辑,但我相信代码
call_user_func_array(array(&$stmt, 'bindparams'), $array_of_params);
$ stmt前面的引用不是必需的。由于$stmt
是对象,bindparams
是该对象中的方法,因此不需要引用。它应该是:
call_user_func_array(array($stmt, 'bindparams'), $array_of_params);
有关详细信息,请参阅Callback Functions上的PHP手册。“
答案 3 :(得分: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();
答案 4 :(得分:0)
动态绑定参数的更现代方法是通过splat / spread运算符(...
)。
假设:
$values
PHP5.6及更高版本的代码:
$stmt->bind_param(str_repeat('s', count($values)), ...$values);