【问题标题】:Zend TableGateway can't execute 2 consecutive queryZend TableGateway 无法执行 2 个连续查询
【发布时间】:2018-04-17 14:39:37
【问题描述】:

自从我从 slim-api-skeleton 开始使用 Zend TableGateway 学习 Slim 已经有几周了。

我似乎无法使用 TableGateway 运行 2 个连续查询。它总是产生(不仅仅是更新):

"Statement couldn't be produced with sql: UPDATE `users` SET `last_access` = NOW() WHERE `id` = ?"

这是 ZendUserRepository 类中的代码:

public function __construct(array $config) {
    $adapter = new Adapter($config);
    $this->table = new TableGateway("users", $adapter);
}

...

public function footprint(int $id): void {
    $data = ['last_access' => new Predicate\Expression('NOW()')];
    $where = ['id' => $id];
    $this->table->update($data, $where);
}

public function authenticate(string $username, string $password): bool {
    $where = [
        'username' => $username,
        new Predicate\IsNotNull('roles')
    ];
    $rowset = $this->table->select($where);
    if (null === $row = $rowset->current()) {
        return false;
    }
    $data = (array) $row;
    if(password_verify($password, $data['password'])) {
        $this->footprint($data['id']);
        return true;
    }
    return false;
}

这让我沮丧了好几天。由于更新函数也使用2个连续查询。

public function update(User $user): void {
    $data = $this->hydrator->extract($user);
    if (!$this->contains($user)) {
        throw new UserNotFoundException;
    }
    $where = ["id" => $user->getId()];
    $this->table->update($data, $where);
}

public function contains(User $user): bool {
    try {
        $this->get($user->getId());
    } catch (UserNotFoundException $exception) {
        return false;
    }
    return true;
}

谢谢。

【问题讨论】:

    标签: zend-framework slim


    【解决方案1】:

    使用 PHPUnit 测试,我得到以下结果:

    Zend\Db\Adapter\Exception\InvalidQueryException: Statement couldn't be produced with sql: UPDATE `users` SET `last_access` = NOW() WHERE `id` = ?
    
    /vagrant/vendor/zendframework/zend-db/src/Adapter/Driver/Mysqli/Statement.php:208
    /vagrant/vendor/zendframework/zend-db/src/Adapter/Driver/Mysqli/Statement.php:229
    /vagrant/vendor/zendframework/zend-db/src/TableGateway/AbstractTableGateway.php:391
    /vagrant/vendor/zendframework/zend-db/src/TableGateway/AbstractTableGateway.php:349
    /vagrant/src/Infrastructure/ZendUserRepository.php:90
    /vagrant/src/Infrastructure/ZendUserRepository.php:104
    /vagrant/src/Application/User/UserAuthenticationHandler.php:19
    /vagrant/tests/Application/User/UserAuthenticationHandlerTest.php:41
    
    Caused by
    Zend\Db\Adapter\Exception\ErrorException: Commands out of sync; you can't run this command now
    

    从 google 到 https://stackoverflow.com/a/614741/3164944

    你不能同时有两个查询,因为 mysqli 使用无缓冲查询 默认(对于准备好的语句;与原版相反 mysql_query)。您可以将第一个获取到数组中,然后 循环通过它,或者告诉 mysqli 缓冲查询(使用 $stmt->store_result())。


    通过附加配置解决:

    [
        "driver" => "Mysqli",
        "database" => getenv("DB_NAME"),
        "username" => getenv("DB_USER"),
        "password" => getenv("DB_PASSWORD"),
        "hostname" => getenv("DB_HOST"),
        "charset" => "utf8",
        'options' => ['buffer_results' => true],
    ]
    

    来自https://stackoverflow.com/a/43863554/3164944

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-11-14
      • 1970-01-01
      • 2014-06-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多