codeigniter使用odbc数据库驱动程序的问题

Nir*_*ish 2 php sql-server odbc codeigniter

我遇到了codeigniter的odbc驱动程序的一个奇怪的问题.我正在使用FreeTDS从Linux机器连接到MSSQL 2008机器.

虽然我得到'num_rows'函数总是返回-1,这完全是一个数据库/驱动程序问题 - 由于某种原因,当我尝试创建 - > result()时,整个应用程序崩溃(错误500,有时只是一个空白页),如果我很幸运,我收到一条错误消息,通知我该应用程序因为试图分配2 TB的内存(!)而死亡.

这种情况不规律地发生,即:每次刷新.有时它运行正常,有时页面返回错误500,有时它会给出内存分配错误 - 在任何情况下,它都不是真正可以用percision再现的东西,而且查询非常简单.

有谁的想法?

Rob*_*ert 6

哈哈,这也发生在我身上!而且向开发者抱怨它,他们忽略了我.

当你调用result()时,它将遍历每一个可能的结果,并将记录存储到一个庞大的内部数组中.system/database/DB_result.php在result_object()和result_array()的末尾看到while循环

有三种方法可以修复它.

简单的方法:

LIMIT(或TOP在MSSQL中)您的SQL查询结果.

SELECT TOP(100) * FROM Table
Run Code Online (Sandbox Code Playgroud)

更新的无缓冲方式:

使用在提出此问题2年后引入unbuffered_row()功能.

$query = $this->db->query($sql);
// not $query->result() because that loads everything into an internal array.
// and not $query->first_row() because it does the same thing (as of 2013-04-02)
while ($record = $query->unbuffered_row('array')) { 
    // code...
}
Run Code Online (Sandbox Code Playgroud)

困难的方式:

使用一个使用PHP5迭代器的正确结果对象(开发人员不喜欢它,因为它排除了php4).在DB_result.php文件中执行类似这样的操作:

-class CI_DB_result {
+class CI_DB_result implements Iterator {

    var $conn_id        = NULL;
    var $result_id      = NULL;
    var $result_array   = array();
    var $result_object  = array();
-   var $current_row    = 0;
+   var $current_row    = -1;
    var $num_rows       = 0;
    var $row_data       = NULL;
+   var $valid          = FALSE;


    /**
    function _fetch_assoc() { return array(); } 
    function _fetch_object() { return array(); }

+   /**
+    * Iterator implemented functions
+    * http://us2.php.net/manual/en/class.iterator.php
+    */
+   
+   /**
+    * Rewind the database back to the first record
+    *
+    */
+   function rewind()
+   {
+       if ($this->result_id !== FALSE AND $this->num_rows() != 0) {
+           $this->_data_seek(0);
+           $this->valid = TRUE;
+           $this->current_row = -1;
+       }
+   }
+   
+   /**
+    * Return the current row record.
+    *
+    */
+   function current()
+   {
+       if ($this->current_row == -1) {
+           $this->next();
+       }
+       return $this->row_data;
+   }
+   
+   /**
+    * The current row number from the result
+    *
+    */
+   function key()
+   {
+       return $this->current_row;
+   }
+   
+   /**
+    * Go to the next result.
+    *
+    */
+   function next()
+   {
+       $this->row_data = $this->_fetch_object();
+       if ($this->row_data) {
+           $this->current_row++;
+           if (!$this->valid)
+               $this->valid = TRUE;
+           return TRUE;
+       } else {
+           $this->valid = FALSE;
+           return FALSE;
+       }
+   }
+   
+   /**
+    * Is the current_row really a record?
+    *
+    */
+   function valid()
+   {
+       return $this->valid;
+   }
+   
 }
 // END DB_result class
Run Code Online (Sandbox Code Playgroud)

然后使用它,而不是调用$query->result()你只使用对象而不是->result()像最后一样$query.所有内部CI的东西仍然适用result().

$query = $this->db->query($sql);
foreach ($query as $record) { // not $query->result() because that loads everything into an internal array.
    // code...
}
Run Code Online (Sandbox Code Playgroud)

顺便说一句,我的迭代器的代码与自己的代码工作有一些逻辑问题与整个-1的事情,所以不要同时使用$query->result(),并$query在同一对象上.如果有人想解决这个问题,那你很棒.

  • 更正,这*不是我的设置的问题,但是当我完全重写驱动程序时,我发现你的代码非常有用,我的结果对象现在是纯php5,非常好. (2认同)