bind_param()与call_user_func_array()
首先介绍call_user_func_array()函数
这个函数主要用来调用函数,避免了直接调用,而且可以使用参数数组,具有很大的灵活性。尤其是与bind_param配合使用,十分绝妙。
用法:
function foo($a,$b) {
//todo
}
我们可以这样调用:
call_uesr_func_array('foo', array($a, $b)); //有几个参数就用几个元素的数组,如果只有一个参数就用一个
元素的数组,注意,一定是数组。
如果是对象里面的方法:
private function foo($a, $b) {
//todo
}
声明了对象$o;
我们可以这样调用
call_user_func_array(array($o, 'foo'), array($a, $b)); //第一个参数也是一个数组。
======================================================================================
我们再看看bind_param()
$stmt = $cnn->prepare('select * from user where id=?');
$stmt->bind_param('?', $condition);
$condition = 2;
$stmt->execute();
关键是bind_param的第二个参数,一定是一个引用变量reference。如果我们调用时直接用一个常量,例如$stmt->bind_param('?', 2);会报错,一定要传一个变量进去。
请看下面例程:
function foo(&$a) {
echo $a;
}
$a = 2;
foo($a); //这样调用才行,一定要传一个变量进去,好让函数的参数索引有值可引!
注意一点:为什么$stmt可以先绑定一个空变量再赋值呢?因为$stmt->bind_param()只是准备阶段,后面还有很多机制把值赋上去。(引用这块还是不太懂,有时间再弄)。
这就有一个问题了。
如果我们做连贯操作
where(array('id' => 1, 'name' => 'kk'))
那么,生成的$where='where id=? and name=?'
$data=array(1,'kk'),这是按顺序入数组的。
然后再unshift两个s进去,最后$data=array('ss', 1, 'kk');
我们在绑定参数的时候
call_user_func_array(array($stmt, 'bind_param'), $data) => $stmt-bind_param('ss', 1, 'kk'); //数组三个元素做三个参数,第一个'ss'没问题,但第二第三就不行了,因为是常量!报错
解决,把$data数组里面的元素,由常量变为引用就行了!
private function arr2refer($value) {
$refs = array();
foreach ($value as $k => $v) {
$refs[$k] = &$value[$k];
}
return $refs;
}
$refs = array();
foreach ($value as $k => $v) {
$refs[$k] = &$value[$k];
}
return $refs;
}
call_user_func_array(array($stmt, 'bind_param'), $this->arr2ref($data));