所以我已经成功编写了一个脚本,它将准备并将任何参数绑定到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
答案 0 :(得分:1)
将$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;