Zend framework prepareStatementForSqlObject 和 execute 不起作用


Zend framework prepareStatementForSqlObject and execute do not work

在ZF2中,我想将来自html表单的数据保存到数据库中。我有一个数据映射器类(简化版):

class OrganizationMapper 
{
protected $dbAdapter;
public function __construct(
    AdapterInterface $dbAdapter,
) {
    $this->dbAdapter = $dbAdapter;
}
    public function save()
    {
        $action = new Insert('parties');
        $action->values(['created' => 'NOW()']);
        $sql = new Sql($this->dbAdapter);
        $stmt   = $sql->prepareStatementForSqlObject($action);
        $result = $stmt->execute();
    }
}

Parties具有id列(int、auto_increment、主键)和created列(时间戳)。

按下 html 表单中的提交按钮后,将调用映射器的save方法。执行$stmt->execute()后,我应该在Parties表中看到一个新行。但是我检查了数据库,什么都没有。问题很可能出在$stmt->execute(),因为如果我在$stmt->execute()之后放'Zend'Debug'Debug::dump($action) + die(),页面不会die()并显示原始形式。但是,如果我在没有准备的情况下只执行原始查询,一切正常,如下所示:

   $sql = 'insert into parties (created) values (NOW());';
   $this->dbAdapter->query($sql, 'Zend'Db'Adapter'Adapter::QUERY_MODE_EXECUTE);

你能说出哪里出了问题吗?

以防万一,以下是'Zend'Debug'Debug::dump($stmt)+die()的结果

object(Zend'Db'Adapter'Driver'Pdo'Statement)#409 (9) {
  ["pdo":protected] => object(PDO)#405 (0) {
  }
  ["profiler":protected] => NULL
  ["driver":protected] => object(Zend'Db'Adapter'Driver'Pdo'Pdo)#255 (4) {
    ["connection":protected] => object(Zend'Db'Adapter'Driver'Pdo'Connection)#256 (8) {
      ["driver":protected] => *RECURSION*
      ["resource":protected] => object(PDO)#405 (0) {
      }
      ["dsn":protected] => string(62) "mysql:dbname=SampleDatabase;host=localhost;charset=utf8"
      ["connectionParameters":protected] => array(5) {
        ["driver"] => string(3) "Pdo"
        ["username"] => string(7) "MyUserName"
        ["password"] => string(12) "MySecretPassword"
        ["dsn"] => string(62) "mysql:dbname=SampleDatabase;host=localhost;charset=utf8"
        ["driver_options"] => array(3) {
          [1002] => string(16) "SET NAMES 'UTF8'"
          [1003] => string(16) "SET NAMES 'UTF8'"
          [1004] => string(16) "SET NAMES 'UTF8'"
        }
      }
      ["driverName":protected] => string(5) "mysql"
      ["inTransaction":protected] => bool(false)
      ["nestedTransactionsCount":protected] => int(0)
      ["profiler":protected] => NULL
    }
    ["statementPrototype":protected] => object(Zend'Db'Adapter'Driver'Pdo'Statement)#257 (9) {
      ["pdo":protected] => NULL
      ["profiler":protected] => NULL
      ["driver":protected] => *RECURSION*
      ["sql":protected] => string(0) ""
      ["isQuery":protected] => NULL
      ["parameterContainer":protected] => NULL
      ["parametersBound":protected] => bool(false)
      ["resource":protected] => NULL
      ["isPrepared":protected] => bool(false)
    }
    ["resultPrototype":protected] => object(Zend'Db'Adapter'Driver'Pdo'Result)#258 (9) {
      ["statementMode":protected] => string(7) "forward"
      ["fetchMode":protected] => int(2)
      ["resource":protected] => NULL
      ["options":protected] => NULL
      ["currentComplete":protected] => bool(false)
      ["currentData":protected] => NULL
      ["position":protected] => int(-1)
      ["generatedValue":protected] => NULL
      ["rowCount":protected] => NULL
    }
    ["features":protected] => array(0) {
    }
  }
  ["sql":protected] => string(51) "INSERT INTO `parties` (`created`) VALUES (:created)"
  ["isQuery":protected] => NULL
  ["parameterContainer":protected] => object(Zend'Db'Adapter'ParameterContainer)#400 (4) {
    ["data":protected] => array(1) {
      ["created"] => string(5) "NOW()"
    }
    ["positions":protected] => array(1) {
      [0] => string(7) "created"
    }
    ["errata":protected] => array(0) {
    }
    ["maxLength":protected] => array(0) {
    }
  }
  ["parametersBound":protected] => bool(false)
  ["resource":protected] => NULL
  ["isPrepared":protected] => bool(false)
}
你可以

写:

use Zend'Db'Sql'Expression;
$action->values(['created' => new Expression('NOW()')]);

意外找到了解决方案。罪魁祸首是

$action->values(['created' => 'NOW()']);

我想准备好的语句无法识别NOW()函数。日期 + 时间应该用 php 传递。我用了这个:

$action->values(['created' => (new 'DateTime('now'))->format('Y-m-d H:i:s')]);