如何在PHP中动态绑定mysqli bind_param参数?
我一直在学习在sql查询中使用准备好的和绑定的语句,到目前为止,我已经想到了这一点,它工作正常,但当涉及到多个参数或不需要参数时,它根本不是动态的如何在PHP中动态绑定mysqli bind_param参数?,php,arrays,mysqli,bind,prepared-statement,Php,Arrays,Mysqli,Bind,Prepared Statement,我一直在学习在sql查询中使用准备好的和绑定的语句,到目前为止,我已经想到了这一点,它工作正常,但当涉及到多个参数或不需要参数时,它根本不是动态的 public function get_result($sql,$parameter) { # create a prepared statement $stmt = $this->mysqli->prepare($sql); # bind parameters for markers
public function get_result($sql,$parameter)
{
# create a prepared statement
$stmt = $this->mysqli->prepare($sql);
# bind parameters for markers
# but this is not dynamic enough...
$stmt->bind_param("s", $parameter);
# execute query
$stmt->execute();
# these lines of code below return one dimentional array, similar to mysqli::fetch_assoc()
$meta = $stmt->result_metadata();
while ($field = $meta->fetch_field()) {
$var = $field->name;
$$var = null;
$parameters[$field->name] = &$$var;
}
call_user_func_array(array($stmt, 'bind_result'), $parameters);
while($stmt->fetch())
{
return $parameters;
//print_r($parameters);
}
# close statement
$stmt->close();
}
这就是我如何调用对象类
$mysqli = new database(DB_HOST,DB_USER,DB_PASS,DB_NAME);
$output = new search($mysqli);
有时我不需要传入任何参数
$sql = "
SELECT *
FROM root_contacts_cfm
";
print_r($output->get_result($sql));
$sql = "
SELECT *
FROM root_contacts_cfm
WHERE root_contacts_cfm.cnt_id = ?
ORDER BY cnt_id DESC
";
print_r($output->get_result($sql,'1'));
$sql = "
SELECT *
FROM root_contacts_cfm
WHERE root_contacts_cfm.cnt_id = ?
AND root_contacts_cfm.cnt_firstname = ?
ORDER BY cnt_id DESC
";
print_r($output->get_result($sql,'1','Tk'));
有时候我只需要一个参数
$sql = "
SELECT *
FROM root_contacts_cfm
";
print_r($output->get_result($sql));
$sql = "
SELECT *
FROM root_contacts_cfm
WHERE root_contacts_cfm.cnt_id = ?
ORDER BY cnt_id DESC
";
print_r($output->get_result($sql,'1'));
$sql = "
SELECT *
FROM root_contacts_cfm
WHERE root_contacts_cfm.cnt_id = ?
AND root_contacts_cfm.cnt_firstname = ?
ORDER BY cnt_id DESC
";
print_r($output->get_result($sql,'1','Tk'));
有时我只需要一个以上的参数
$sql = "
SELECT *
FROM root_contacts_cfm
";
print_r($output->get_result($sql));
$sql = "
SELECT *
FROM root_contacts_cfm
WHERE root_contacts_cfm.cnt_id = ?
ORDER BY cnt_id DESC
";
print_r($output->get_result($sql,'1'));
$sql = "
SELECT *
FROM root_contacts_cfm
WHERE root_contacts_cfm.cnt_id = ?
AND root_contacts_cfm.cnt_firstname = ?
ORDER BY cnt_id DESC
";
print_r($output->get_result($sql,'1','Tk'));
因此,我认为这条线不够动态,无法完成上述动态任务
$stmt->bind_param("s", $parameter);
为了动态构建一个bind_参数,我在网上的其他帖子中发现了这个
call_user_func_array(array(&$stmt, 'bind_params'), $array_of_params);
我试着修改了一些代码,但是我一无所获
if (strnatcmp(phpversion(),'5.3') >= 0) //Reference is required for PHP 5.3+
{
$refs = array();
foreach($arr as $key => $value)
$array_of_param[$key] = &$arr[$key];
call_user_func_array(array(&$stmt, 'bind_params'), $array_of_params);
}
为什么??你知道我该怎么做吗
或者有更好的解决方案
或者也许有更好的解决方案
这个答案对你并没有多大帮助,但是你应该认真考虑从MySqLi切换到./P>
这主要是因为PDO使用内置函数完成了您在mysqli中尝试执行的操作。除了具有,还可以采用参数数组
PDO很容易扩展,添加方便的方法来获取所有内容并返回,而不是进行准备-执行舞蹈非常容易
或者也许有更好的解决方案
这个答案对你并没有多大帮助,但是你应该认真考虑从MySqLi切换到./P>
这主要是因为PDO使用内置函数完成了您在mysqli中尝试执行的操作。除了具有,还可以采用参数数组
PDO很容易扩展,添加方便的方法来获取所有内容并返回,而不是执行“准备-执行”舞蹈非常容易。找到了mysqli的答案:
public function get_result($sql,$types = null,$params = null)
{
# create a prepared statement
$stmt = $this->mysqli->prepare($sql);
# bind parameters for markers
# but this is not dynamic enough...
//$stmt->bind_param("s", $parameter);
if($types&&$params)
{
$bind_names[] = $types;
for ($i=0; $i<count($params);$i++)
{
$bind_name = 'bind' . $i;
$$bind_name = $params[$i];
$bind_names[] = &$$bind_name;
}
$return = call_user_func_array(array($stmt,'bind_param'),$bind_names);
}
# execute query
$stmt->execute();
# these lines of code below return one dimentional array, similar to mysqli::fetch_assoc()
$meta = $stmt->result_metadata();
while ($field = $meta->fetch_field()) {
$var = $field->name;
$$var = null;
$parameters[$field->name] = &$$var;
}
call_user_func_array(array($stmt, 'bind_result'), $parameters);
while($stmt->fetch())
{
return $parameters;
//print_r($parameters);
}
# the commented lines below will return values but not arrays
# bind result variables
//$stmt->bind_result($id);
# fetch value
//$stmt->fetch();
# return the value
//return $id;
# close statement
$stmt->close();
}
说到这一点,mysqli真是太差劲了。我想我应该迁移到PDO 找到了mysqli的答案:
public function get_result($sql,$types = null,$params = null)
{
# create a prepared statement
$stmt = $this->mysqli->prepare($sql);
# bind parameters for markers
# but this is not dynamic enough...
//$stmt->bind_param("s", $parameter);
if($types&&$params)
{
$bind_names[] = $types;
for ($i=0; $i<count($params);$i++)
{
$bind_name = 'bind' . $i;
$$bind_name = $params[$i];
$bind_names[] = &$$bind_name;
}
$return = call_user_func_array(array($stmt,'bind_param'),$bind_names);
}
# execute query
$stmt->execute();
# these lines of code below return one dimentional array, similar to mysqli::fetch_assoc()
$meta = $stmt->result_metadata();
while ($field = $meta->fetch_field()) {
$var = $field->name;
$$var = null;
$parameters[$field->name] = &$$var;
}
call_user_func_array(array($stmt, 'bind_result'), $parameters);
while($stmt->fetch())
{
return $parameters;
//print_r($parameters);
}
# the commented lines below will return values but not arrays
# bind result variables
//$stmt->bind_result($id);
# fetch value
//$stmt->fetch();
# return the value
//return $id;
# close statement
$stmt->close();
}
说到这一点,mysqli真是太差劲了。我想我应该迁移到PDO 使用PHP5.6,您可以借助(
..$var
)和
例如:
$mysqli = new database(DB_HOST,DB_USER,DB_PASS,DB_NAME);
$output = new search($mysqli);
$sql = "SELECT * FROM root_contacts_cfm WHERE root_contacts_cfm.cnt_id = ?
AND root_contacts_cfm.cnt_firstname = ?
ORDER BY cnt_id DESC";
$res = $output->get_result($sql, 'ss',array('1','Tk'));
while($row = res->fetch_assoc()){
echo $row['fieldName'] .'<br>';
}
$mysqli=新数据库(数据库主机、数据库用户、数据库通行证、数据库名称);
$output=新搜索($mysqli);
$sql=“从root\u contacts\u cfm中选择*,其中root\u contacts\u cfm.cnt\u id=?
和root_contacts_cfm.cnt_firstname=?
按cnt_id DESC订购”;
$res=$output->get_result($sql,'ss',array('1','Tk');
而($row=res->fetch_assoc()){
echo$row['fieldName']。
;
}
使用PHP5.6,您可以在(..$var
的帮助下轻松完成这项工作,并使用
例如:
$mysqli = new database(DB_HOST,DB_USER,DB_PASS,DB_NAME);
$output = new search($mysqli);
$sql = "SELECT * FROM root_contacts_cfm WHERE root_contacts_cfm.cnt_id = ?
AND root_contacts_cfm.cnt_firstname = ?
ORDER BY cnt_id DESC";
$res = $output->get_result($sql, 'ss',array('1','Tk'));
while($row = res->fetch_assoc()){
echo $row['fieldName'] .'<br>';
}
$mysqli=新数据库(数据库主机、数据库用户、数据库通行证、数据库名称);
$output=新搜索($mysqli);
$sql=“从root\u contacts\u cfm中选择*,其中root\u contacts\u cfm.cnt\u id=?
和root_contacts_cfm.cnt_firstname=?
按cnt_id DESC订购”;
$res=$output->get_result($sql,'ss',array('1','Tk');
而($row=res->fetch_assoc()){
echo$row['fieldName']。
;
}
使用PHP 5.6或更高版本:
$stmt->bind_param(str_repeat("s", count($data)), ...$data);
使用PHP5.5或更低版本,您可能(我也确实)希望以下功能能够正常工作:
call_user_func_array(
array($stmt, "bind_param"),
array_merge(array(str_repeat("s", count($data))), $data));
…但是mysqli_stmt::bind_param
希望它的参数是引用,而这会传递一个值列表
您可以通过首先创建对原始数组的引用数组来解决这个问题(尽管这是一个难看的解决方法)
$references_to_data = array();
foreach ($data as &$reference) { $references_to_data[] = &$reference; }
unset($reference);
call_user_func_array(
array($stmt, "bind_param"),
array_merge(array(str_repeat("s", count($data))), $references_to_data));
使用PHP 5.6或更高版本:
$stmt->bind_param(str_repeat("s", count($data)), ...$data);
使用PHP5.5或更低版本,您可能(我也确实)希望以下功能能够正常工作:
call_user_func_array(
array($stmt, "bind_param"),
array_merge(array(str_repeat("s", count($data))), $data));
…但是mysqli_stmt::bind_param
希望它的参数是引用,而这会传递一个值列表
您可以通过首先创建对原始数组的引用数组来解决这个问题(尽管这是一个难看的解决方法)
$references_to_data = array();
foreach ($data as &$reference) { $references_to_data[] = &$reference; }
unset($reference);
call_user_func_array(
array($stmt, "bind_param"),
array_merge(array(str_repeat("s", count($data))), $references_to_data));
我通过应用类似于PDO的系统解决了这个问题。SQL占位符是以双点字符开头的字符串。例:
:id, :name, or :last_name
然后,您可以直接在占位符字符串中指定数据类型,方法是在双精度点之后添加规范字母,并在助记符变量之前添加下划线字符。例:
:i_id (i=integer), :s_name or :s_last_name (s=string)
如果没有添加类型字符,那么函数将通过分析保存数据的php变量来确定数据的类型。例:
$id = 1 // interpreted as an integer
$name = "John" // interpreted as a string
该函数返回一个类型数组和一个值数组,您可以使用该数组在循环中执行php函数mysqli_stmt_bind_param()
$sql = 'SELECT * FROM table WHERE code = :code AND (type = :i_type OR color = ":s_color")';
$data = array(':code' => 1, ':i_type' => 12, ':s_color' => 'blue');
$pattern = '|(:[a-zA-Z0-9_\-]+)|';
if (preg_match_all($pattern, $sql, $matches)) {
$arr = $matches[1];
foreach ($arr as $word) {
if (strlen($word) > 2 && $word[2] == '_') {
$bindType[] = $word[1];
} else {
switch (gettype($data[$word])) {
case 'NULL':
case 'string':
$bindType[] = 's';
break;
case 'boolean':
case 'integer':
$bindType[] = 'i';
break;
case 'double':
$bindType[] = 'd';
break;
case 'blob':
$bindType[] = 'b';
break;
default:
$bindType[] = 's';
break;
}
}
$bindValue[] = $data[$word];
}
$sql = preg_replace($pattern, '?', $sql);
}
echo $sql.'<br>';
print_r($bindType);
echo '<br>';
print_r($bindValue);
$sql='从表中选择*,其中code=:code和(type=:i_type或color=“:s_color”);
$data=数组(“:code'=>1':i_type'=>12':s_color'=>blue”);
$pattern='|(:[a-zA-Z0-9_ \-]+)|';
if(preg_match_all($pattern,$sql,$matches)){
$arr=$matches[1];
foreach($arr作为$word){
如果(strlen($word)>2&&$word[2]==''''''\u'){
$bindType[]=$word[1];
}否则{
开关(gettype($data[$word])){
大小写“NULL”:
大小写“string”:
$bindType[]='s';
打破
“布尔”大小写:
“整数”情况:
$bindType[]=“i”;
打破
双格:
$bindType[]='d';
打破
案例“blob”:
$bindType[]=“b”;
打破
违约:
$bindType[]='s';
打破
}
}
$bindValue[]=$data[$word];
}
$sql=preg_replace($pattern,“?”,$sql);
}
回显$sql。“
”;
打印($bindType);
回声“
”;
打印(bindValue);
我通过应用类似于PDO的系统解决了这个问题。SQL占位符是以双点字符开头的字符串。例:
:id, :name, or :last_name
然后,您可以直接在占位符字符串中指定数据类型,方法是在dou之后立即添加规范字母