Finder 方法在调用 all() 时仅返回计数

Finder Method returning only count when calling all()

所以。我想找到执行此操作的 "correct" 方法。我想检索数据库中所有条目的列表,以一种很好的、​​人类可读的方式格式化 "created" 和 "modified" 字段。

在 Cakephp2.x 中,我会使用 afterFind 方法。看到 Cakephp3 中有 none,我转向这个 blog post,发现我必须使用 formatResults 函数。很自然地,我尝试了这个(以及同一件事的许多其他迭代):

public function findAllForView(Query $query, array $options)
{
  $test = $query->formatResults(function ($results) {
    $r = $results->map(function ($row) {
      $row['created'] = new Time($row['created']);
      $row['created'] = $row['created']->nice();
      $row['modified'] = new Time($row['modified']);
      $row['modified'] = $row['modified']->nice();
      return $row;
    });
    return $r;
  });
  debug($test);
  foreach ($test as $t) {
    debug($t);
  }
  debug($test->all());
  return $test;
}

变量$test returns:

object(Cake\ORM\Query) {

'(help)' => 'This is a Query object, to get the results execute or iterate it.',
'sql' => 'SELECT Casinos.id AS `Casinos__id`, Casinos.name AS `Casinos__name`, Casinos.address AS `Casinos__address`, Casinos.address2 AS `Casinos__address2`, Casinos.city AS `Casinos__city`, Casinos.province AS `Casinos__province`, Casinos.country AS `Casinos__country`, Casinos.latitude AS `Casinos__latitude`, Casinos.longitude AS `Casinos__longitude`, Casinos.created AS `Casinos__created`, Casinos.modified AS `Casinos__modified` FROM casinos Casinos',
'params' => [],
'defaultTypes' => [
    'Casinos__id' => 'integer',
    'Casinos.id' => 'integer',
    'id' => 'integer',
    'Casinos__name' => 'string',
    'Casinos.name' => 'string',
    'name' => 'string',
    'Casinos__address' => 'string',
    'Casinos.address' => 'string',
    'address' => 'string',
    'Casinos__address2' => 'string',
    'Casinos.address2' => 'string',
    'address2' => 'string',
    'Casinos__city' => 'string',
    'Casinos.city' => 'string',
    'city' => 'string',
    'Casinos__province' => 'string',
    'Casinos.province' => 'string',
    'province' => 'string',
    'Casinos__country' => 'string',
    'Casinos.country' => 'string',
    'country' => 'string',
    'Casinos__latitude' => 'float',
    'Casinos.latitude' => 'float',
    'latitude' => 'float',
    'Casinos__longitude' => 'float',
    'Casinos.longitude' => 'float',
    'longitude' => 'float',
    'Casinos__created' => 'datetime',
    'Casinos.created' => 'datetime',
    'created' => 'datetime',
    'Casinos__modified' => 'datetime',
    'Casinos.modified' => 'datetime',
    'modified' => 'datetime'
],
'decorators' => (int) 0,
'executed' => false,
'hydrate' => true,
'buffered' => true,
'formatters' => (int) 1,
'mapReducers' => (int) 0,
'contain' => [],
'matching' => [],
'extraOptions' => [],
'repository' => object(App\Model\Table\CasinosTable) {

    'registryAlias' => 'Casinos',
    'table' => 'casinos',
    'alias' => 'Casinos',
    'entityClass' => 'App\Model\Entity\Casino',
    'associations' => [
        (int) 0 => 'users'
    ],
    'behaviors' => [
        (int) 0 => 'Timestamp'
    ],
    'defaultConnection' => 'default',
    'connectionName' => 'default'

}

}

变量$r returns:

object(App\Model\Entity\Casino) {

'id' => (int) 1,
'name' => 'Test Casino',
'address' => 'Somewhere avenue',
'address2' => null,
'city' => 'Somewhere',
'province' => 'Province',
'country' => 'Alwaysland',
'latitude' => (float) 51.1644,
'longitude' => (float) -114.093,
'created' => 'Jun 8, 2016, 10:04 PM',
'modified' => 'Jun 8, 2016, 10:04 PM',
'[new]' => false,
'[accessible]' => [
    '*' => true
],
'[dirty]' => [
    'created' => true,
    'modified' => true
],
'[original]' => [
    'created' => object(Cake\I18n\FrozenTime) {

        'time' => '2016-06-08T22:04:53+00:00',
        'timezone' => 'UTC',
        'fixedNowTime' => false

    },
    'modified' => object(Cake\I18n\FrozenTime) {

        'time' => '2016-06-08T22:04:55+00:00',
        'timezone' => 'UTC',
        'fixedNowTime' => false

    }
],
'[virtual]' => [],
'[errors]' => [],
'[invalid]' => [],
'[repository]' => 'Casinos'

}

根据 The Query builder part of the bookall() 应该 return 结果集。然而,当 $test->all() 被调用时,我得到了这个惊喜:

object(Cake\Datasource\ResultSetDecorator) {

'count' => (int) 2

}

有人能给我指出正确的方向吗?我真的很困惑,我可能只使用 toArray 方法,但我仍然想知道为什么这不起作用,因为我仍在学习新的 ORM 系统。

转储对象不一定会给您对象结构的实际表示,而是自定义格式的调试信息,通过 the magic __debugInfo() method.

定义

对于结果集装饰器(这是你在应用结果格式化器时得到的),调试信息只包含计数,即集合中的结果数,参见

https://github.com/cakephp/cakephp/blob/3.2.10/src/Collection/Collection.php#L95-L100

结果集装饰器是一个集合,可以像使用 $test 一样进行迭代。 beforeafter调用all()的区别在于前者会在内部自动调用all(),所以最后它实际上是一样的。

您应该 return 一个数组还是一个结果集,取决于您 want/need 您 API 的行为方式。返回数组将限制对结果的处理,为了应用集合方法,必须将数组转换回集合,因此从性能的角度来看,return 会更好集合。

另见