我为PHP创建了一个单例数据库类。我以为它很好用,但实际上不是。我现在做一个页面,有3个查询。1检查相册是否存在,1检查用户是否拥有相册,另一个从相册中获取照片。
现在在我的第三个查询中,我填充了一个对象,但是前2个查询的结果也在该数组中,所以我得到了通知!
下面是一个例子:
Array
(
[0] => Array
(
[id] => 2
[name] => My new album 1
[slug] => my-new-album-1
[user_id] => 1
[views] => 0
[datecreated] => 2013/03/23 16:00:43
)
[1] => Array
(
[id] => 3
[name] => My new album 1
[slug] => my-new-album-1
[user_id] => 1
[views] => 0
[datecreated] => 2013/03/23 23:51:58
)
[2] => Array
(
[id] => 2
)
[3] => Array
(
[id] => 117
[title] =>
[location_id] =>
[date] => 2013-03-30 00:42:26
[user_id] => 1
[album_id] => 2
)
这就是我如何做一个查询并返回数组:
mysqli_conn::getInstance()->query($sql)->all_assoc()
这是我的数据库类中执行查询并返回结果的部分:
public function query( $sql ){
$starttime = $this->time_to_float();
$this->query = mysqli_query($this->connection, $sql);
$endtime = $this->time_to_float();
$exectime = ($endtime - $starttime);
if (!$this->query){
throw new Exception(mysqli_error($this->connection));
} else {
$this->arQueryLog[] = array ( 'query' => $sql,
'exectime' => $exectime,
'affected_rows' => mysqli_affected_rows($this->connection),
'last_insert_id' => $this->lastID() );
}
return $this;
}
public function all_assoc ()
{
while($result = mysqli_fetch_assoc($this->query)){
$this->result[] = $result;
}
return $this->result;
}
为什么只有最后一个查询结果在结果数组中?
谢谢! !
2个主要故障,与数据库类无关
- 每个变量必须在使用前初始化。这个代码失败了。 如果您使用本地变量作为本地数据, PHP甚至会原谅上述错误。
public function all_assoc ()
{
$result = array(); //initializing a local variable
while($result = mysqli_fetch_assoc($this->query)){
$result[] = $result;
}
return $result;
}
和这个all_assoc函数最好使用$result变量而不是使用类属性。
1个与数据库类相关的主要故障。
- 你没有使用占位符,所以,你的查询容易受到SQL注入。
所以,当你已经开始上课时,看看SafeMysql。这会使你的代码更短更安全。
将结果推入类的result属性。因为它是一个单元素,所以以前的值保留在result属性中,并且每次调用all_assoc()方法时,新的结果都会被推入属性中。
在推送新结果之前,应该取消all_assoc()方法中的result属性。
我认为@Jueecy在设计方面可能有一个有效的观点,但由于我们没有访问您的完整实现,让我们使用我们拥有的。
虽然将数据库连接存储在单例中是有意义的,但将查询结果存储在单例中是不合适的(当然不是数据库连接的单例),因为每个请求很可能有多个查询。
从你分享的代码中,我最好的建议是直接返回$query
值(不存储在$this上),并让all_assoc()
(和相关函数)接受$query
并直接返回$result
(不存储在$this上)。
你可以创建一个Query
类来包装$query
和一个Result
类来包装单独的结果集,如果你需要提供自定义逻辑(又名exectime
和arQueryLog
逻辑在你的query()
函数),但是你还没有提供任何代码来显示这是必要的。
祝你好运,
进球法雷尔