所以我成功地编写了一个脚本,该脚本将准备任何参数并将其绑定到 sql 查询,但我在绑定结果部分遇到了问题。
这是我的脚本:
public function query( $query_string, $params = null, $param_types = null) {
//prepare the statement
$stmt = $this->db->prepare($query_string);
//check if the sql query is wrong.
if($stmt === false) {
echo "Wrong SQL: " . $query_string . "<br />Error: " . $this->db->errno . " " . $this->db->error;
}
if($params != null && $param_types != null) {
//build the array that needs to pass the args to bind_param.
$a_params = array();
$a_params[] = &$param_types;
for($i=0; $i<count($params); $i++)
$a_params[] = &$params[$i];
// $stmt->bind_param('s', $param); equivalent
call_user_func_array(array($stmt, 'bind_param'), $a_params);
}
//run the query
$stmt->execute();
$data = $stmt->result_metadata();
$fields = array();
$out = array();
$count = 0;
while($field = $data->fetch_field()) {
$fields[$count++] = &$out[$field->name];
}
call_user_func_array(array($stmt, 'bind_result'), $fields);
$results = array();
$k = 0;
// loop through all result rows
while ($stmt->fetch()) {
$results[$k++] = $out;
print_r($out);
echo "<br />";
}
$stmt->close();
return $results;
}
当我使用 print_r 输出时,它似乎正确绑定,但是当我添加到数组以返回时(用于以后的脚本,它有奇怪的行为)。
对方法的示例调用:
$users = $TCS->query("SELECT name, age, id FROM test");
foreach($users as $user) {
echo $user['name'] . ': <br />';
echo ' age: ' . $user['age'] . '<br />';
echo ' id: ' . $user['id'] . '<br />';
}
但这是我的输出:
Array ( [name] => jake [age] => 18 [id] => 1 )
Array ( [name] => ryan [age] => 19 [id] => 2 )
Array ( [name] => stephen [age] => 16 [id] => 3 )
stephen:
age: 16
id: 3
stephen:
age: 16
id: 3
stephen:
age: 16
id: 3
TL;DR
将$results[$k++] = $out;
更改为$results[$k++] = array_flip(array_flip($out));
以下是对正在发生的事情的解释。
var_dump($out);
// first iteration
array(2) {
["name"]=>
&string(4) "mike"
["id"]=>
&int(1)
}
// second interation
array(2) {
["name"]=>
&string(6) "amanda"
["id"]=>
&int(2)
}
这里要注意的重要一点是与号,它们意味着id
和name
的值是参考。当$out['id']
和$out['name']
时,这些引用所指向的内容将更改。因此语句$results[$k++] = $out;
表示复制$out
并将其分配给$results[$k]
,这包括复制引用。在下一次迭代中,$results[$k-1]
中引用的内容将更改为您背后的新值。
这是一个简单的例子;
$i = 1;
$a = array('id' => &$i);
$b = $a;
$i = 2;
var_dump($a,$b);
// output
array(1) {
["id"]=>
&int(2)
}
array(1) {
["id"]=>
&int(2)
}
您可以通过修改以下行来解决此问题:
$results[$k++] = $out;
到$results[$k++] = array_flip(array_flip($out));
内部array_flip
将取消引用这些值并使其成为键,外部翻转将反转该过程。
但我建议重写下面的所有内容$stmt->execute()
如下所示。
//run the query
$stmt->execute();
$result = $stmt->get_result();
if (!$result) { return array(); }
$ret = array();
while ($row = $result->fetch_assoc()) {
array_push($ret, $row);
}
return $ret;