使用MySQLi返回大型数据集

时间:2015-07-21 03:28:37

标签: php mysqli

我一直致力于一个基本类来处理我的大多数简单的MySQLi查询(例如简单的选择),并且遇到了一些与我如何返回数据相关的问题迄今。以下是相关函数的示例:

public function selectFromWhere($conn, $columns, $table, $where, $vars, $limit) {
    $sql = "SELECT %s FROM %s WHERE %s%s";
    $l = ($limit == 0) ? '' : " LIMIT " . $limit;
    $sql = sprintf($sql, $columns, $table, $where, $l);
    if($query = $conn->prepare($sql)) {
        $a = $this->parameterizeArray($vars);
        if (call_user_func_array(array($query, "bind_param"), $this->refValues($a))) {
            $data = array();
            $query->execute();
            $row = $query->get_result();
            while($r = $row->fetch_assoc()) {
                array_push($data, $r);
            }
            if (count($data) == 1 && $limit == 1) {
                $data = $data[0];
            }
            return $data;
        }else{
            return false;
        }
    }else{
        return false;
    }
}

该函数运行良好,获取一系列变量并格式化它们以使用bind_param。问题是一个相当明显的问题,我将每一行添加到一个数组,然后返回该数组。 (如果限制设置为1,只返回一个简单的关联数组)我知道这是一种可怕的做法,并且当我创建函数时没有考虑到它,但是我只是遇到了明显的问题。内存问题..大数据集会占用太多内存并导致问题。 (例如,达到设置的php内存限制)

我的想法是返回一个数组,其中的每一行都作为一个数组,这样我就可以在需要时简单地运行foreach。这是为了避免为每个单独的查询打扰相同的4-5个MySQLi行。

我应该简单地返回fetch_assoc()响应并在我的代码中运行while循环使用此函数而不是foreach循环吗?这是我见过的唯一解决方案,我只是想在这里发帖,看看是否有人有类似的冒险经历,并且可以分享一些见解。

1 个答案:

答案 0 :(得分:0)

首先回答你的问题。 http://php.net/manual/en/mysqli-result.fetch-all.php

$row->fetch_all(MYSQLI_ASSOC);

或者如果您的问题是希望它作为简单数组而不是关联数组返回

$row->fetch_all(MYSQLI_NUM);

其次,您不应该重复代码行,不存在此功能,或者我是否误解了您的问题

$row = $query->get_result();
return arrayMyData($row)
...
function arrayMyData($row){
  $data = array();
  while($r = $row->fetch_assoc()) {
    array_push($data, $r);
  }
  if (count($data) == 1 && $limit == 1) {
    $data = $data[0];
  }
  return $data;
}

应该代表你应该做什么,不要重复自己。

EDIT 如果我们想进一步处理内存问题,假设您正在独立处理每一行

$row = $query->get_result();
return arrayMyData($row, 'myNumberCruncher')
...
function arrayMyData($row, $func){
  $data = array();
  while($r = $row->fetch_assoc()) {
    /*array_push($data,*/ 
    $func($r);
    /*);*/
  }
  if (count($data) == 1 && $limit == 1) {
    $data = $data[0];
  }
  return $data;
}
function myNumberCruncher{
...
}