首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SQLite (php) fetchArray()不会在结果结束时停止

SQLite (php) fetchArray()不会在结果结束时停止
EN

Stack Overflow用户
提问于 2017-05-24 21:07:58
回答 1查看 303关注 0票数 0

我在试着测试我的一些模特。我使用依赖注入来选择数据库方法。我已经有了工作模型,但我试图回去做测试,这样我就可以开始做TDD而不是希望和祈祷.

不过,在开始测试我的模型之前,我必须先验证我的数据库抽象。我为SQLite3编写了一个抽象,以模仿我为ODBC使用的抽象。我的计划是使用SQLite测试我的模型。

我很难弄清楚为什么while循环在testDbSqLiteFetchObjectImplementation2()中永不停止。在对结果进行迭代时,$this->abstraction->fetchObject()应该返回false。但是它试图继续运行,这会引发一个未定义的属性错误。

)任何不返回false的想法都会受到赞赏:)

db_sqlite.class.php

代码语言:javascript
复制
<?php
/**
 * SQLite Database Abstraction
 *
 * This class is a database abstraction that allows consistent and simplified methods for
 * accessing databases, along with db_db2.class.php and db_odbc.class.php
 **/ 
class DB_sqlite {

  public function __construct($database = "", $user = "", $password = "") {
    $this->db = new SQLite3(':memory:');
  }

  public function prepare($query) {
    $this->statement = $this->db->prepare($query);
  }

  public function bind($vals='') {
    settype($vals, 'array');

    for($i=0; $i<sizeof($vals); $i++) {
        $this->statement->bindValue(($i+1), $vals[$i]); // bindValue index starts at 1, not 0
    }
    $this->result = $this->statement->execute();
    return $this->result;
  }

/**
 * OOP method for retrieving a row of db.  Use in a while statement that assigns results to a var, ie
 *
 *     while($row = $db->fetchObject()) { 
 *       print $row->COLUMN_NAME; 
 *     }
 *
 * @return object Typically the returned object's properties must be accessed as ALL CAPS
 */
  public function fetchObject() {
    return (object)($this->result->fetchArray());
  }

/**
 * Associative Array method of retrieving row
 */
  public function fetchRow() {
    return $this->result->fetchArray(SQLITE3_ASSOC);

  }

sampleTest.php

代码语言:javascript
复制
use PHPUnit\Framework\TestCase;

require("../scripts/task_config.php");

class sampleTest extends TestCase {

    public function setupDb() {
        $this->abstraction = new db_sqlite;
        $fields = 'HISTID NUMERIC,ORGID NUMERIC,STATUS TEXT';

        // note $this->abstraction calls db_sqlite's 'db' property 
        // which is a `new SQLite3(':memory:')` object
        $this->abstraction->db->exec("CREATE TABLE tableName ($fields)");
        $this->abstraction->db->exec("INSERT INTO tableName (HISTID,ORGID,STATUS) VALUES (1, 101, 'c')");
        $this->abstraction->db->exec("INSERT INTO tableName (HISTID,ORGID,STATUS) VALUES (2, 102, 'c')");
    }

    public function testDbSqLiteFetchRowImplementation() {

        $this->setupDb();

        $this->abstraction->prepare("SELECT * FROM tableName WHERE STATUS='c'");
        $this->abstraction->bind();

        $row = $this->abstraction->fetchRow();
        $this->assertEquals('101', $row['ORGID']);

        $row = $this->abstraction->fetchRow();
        $this->assertEquals('102', $row['ORGID']);

    }

    public function testDbSqLiteFetchObjectImplementation() {

        $this->setupDb();

        $this->abstraction->prepare("SELECT * FROM tableName WHERE STATUS='c'");
        $this->abstraction->bind(); // db abstraction binds and executes.

        $row = $this->abstraction->fetchObject();
        $this->assertEquals('101', $row->ORGID);

        $row = $this->abstraction->fetchObject();
        $this->assertEquals('102', $row->ORGID);

    }

    public function testDbSqLiteFetchObjectImplementation2() {

        $this->setupDb();

        $this->abstraction->prepare("SELECT * FROM tableName WHERE STATUS='c'");
        $this->abstraction->bind();

        $count = 0;
        print "\n";
        while($row = $this->abstraction->fetchObject()) {
            print ++$count;
            $collection[] = $row->ORGID;
        }

        $this->assertEquals('101', $collection[0]);
        $this->assertEquals('102', $collection[1]);

    }
}

测试结果

代码语言:javascript
复制
$ cmd //c phpunit
        PHPUnit 6.0.10 by Sebastian Bergmann and contributors.

..E                                                                3 / 3 (100%)
Number of while loop iterations:
123

Time: 339 ms, Memory: 10.00MB

There was 1 error:

1) sampleTest::testDbSqLiteFetchObjectImplementation2
Undefined property: stdClass::$ORGID

X:\tests\sample2Test.php:66

ERRORS!
Tests: 3, Assertions: 4, Errors: 1.
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-05-24 23:39:50

在抽象类中,您要显式地将数据库返回的值转换为对象。因此,即使它是false,在将其转换为object之后,它的值也不会是"falsy“。这使得循环无限地运行。

您需要修复的代码在fetchObject方法中:

代码语言:javascript
复制
return (object)($this->result->fetchArray());

将其改为类似的

代码语言:javascript
复制
$res = $this->result->fetchArray();
if (!$res)
    return $res;
return (object)$res;
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44168487

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档