我使用list从模型中获取数据并且效果很好
此示例来自Cakephp docs
$query = $articles->find('list', [
'keyField' => 'slug',
'valueField' => 'title'
]);
$data = $query->toArray();
我有一个表名假期
id [int] |日期[日期] | name [varchar(200)] |创建了[日期时间]
所以想要一个以日期为关键字,假日为价值的清单 这样的事情
[
'2016-01-01'=>'New Year',
'2016-01-26'=>'Republic Day',
]
所以我通过蛋糕烘焙创建模型并使用此代码来实现它
$holidays = TableRegistry::get('Holidays');
$holidays = $holidays->find('list',[
'keyField' => 'date',
'valueField'=>'name',
])->toArray();
但是它给了我错误
非法偏移类型 InvalidArgumentException
当我使用名称从日期更改keyField时效果很好。
这是日志
2016-04-29 04:26:41错误:[InvalidArgumentException]非法偏移 请求URL:/ sfworxerp / api / attendances / getMonthAttendanceData 堆栈跟踪: F:\的public_html \ sfworxerp \厂商\ cakephp的\ cakephp的\ SRC \收集\迭代\ MapReduce.php(160): 蛋糕\收藏\迭代器\的MapReduce ::发射() F:\的public_html \ sfworxerp \供应商\ CakePHP的\ CakePHP中的\ src \收藏\ CollectionTrait.php(386): Cake \ Collection \ Iterator \ MapReduce-> emit('New Year', 对象(蛋糕\的I18n \ FrozenDate)) F:\的public_html \ sfworxerp \供应商\ CakePHP的\ CakePHP中的\ src \收藏\迭代器\ MapReduce.php(177): 蛋糕\ ORM \ ResultSet->蛋糕\收集{闭合}(对象(应用\模型\实体\假日), 0,Object(Cake \ Collection \ Iterator \ MapReduce)) F:\的public_html \ sfworxerp \厂商\ cakephp的\ cakephp的\ SRC \收集\迭代\ MapReduce.php(132): Cake \ Collection \ Iterator \ MapReduce-> _execute()[内部函数]: 蛋糕\收集\迭代\ MapReduce-> getIterator()方法 F:\的public_html \ sfworxerp \厂商\ cakephp的\ cakephp的\ SRC \收集\ Collection.php(50): IteratorIterator-> __构建体(对象(蛋糕\收集\迭代\ MapReduce的)) F:\的public_html \ sfworxerp \供应商\ CakePHP的\ CakePHP中的\ src \收藏\ CollectionTrait.php(405): 蛋糕\收集\收藏 - > __构建体(对象(蛋糕\收集\迭代\ MapReduce的)) F:\的public_html \ sfworxerp \厂商\ cakephp的\ cakephp的\ SRC \ ORM \ Table.php(1062): Cake \ ORM \ ResultSet-> combine('date','name',NULL) F:\的public_html \ sfworxerp \厂商\ cakephp的\ cakephp的\ SRC \数据源\ QueryTrait.php(490): 蛋糕\ ORM \表-1>蛋糕\ ORM {闭合}(对象(蛋糕\ ORM \结果集)) F:\的public_html \ sfworxerp \厂商\ cakephp的\ cakephp的\ SRC \ ORM \ Query.php(1141): 蛋糕\ ORM \查询 - > _applyDecorators(对象(蛋糕\ ORM \结果集)) F:\的public_html \ sfworxerp \厂商\ cakephp的\ cakephp的\ SRC \数据源\ QueryTrait.php(272): 蛋糕\ ORM \查询 - > _decorateResults(对象(蛋糕\ ORM \结果集)) F:\的public_html \ sfworxerp \厂商\ cakephp的\ cakephp的\ SRC \ ORM \ Query.php(871): 蛋糕\ ORM \查询 - > _all() F:\的public_html \ sfworxerp \厂商\ cakephp的\ cakephp的\ SRC \数据源\ QueryTrait.php(288): 蛋糕\ ORM \查询 - >所有() F:\的public_html \ sfworxerp \ SRC \控制器\阿比\ AttendancesController.php(133): Cake \ ORM \ Query-> toArray()[内部函数]: 应用\控制器\阿比\ AttendancesController-> getMonthAttendanceData() F:\的public_html \ sfworxerp \厂商\ cakephp的\ cakephp的\ SRC \控制器\ Controller.php这样(429): call_user_func_array(Array,Array) F:\的public_html \ sfworxerp \厂商\ cakephp的\ cakephp的\ SRC \路由\ Dispatcher.php(114): 蛋糕\控制器\控制器 - > invokeAction() F:\ public_html \ sfworxerp \ vendor \ cakephp \ cakephp \ src \ Routing \ Dispatcher.php(87):Cake \ Routing \ Dispatcher-> _invoke(Object(App \ Controller \ Api \ AttendancesController)) F:\的public_html \ sfworxerp \根目录\的index.php(37): 蛋糕\路由\ Dispatcher->调度(对象(蛋糕\网络\请求), 对象(Cake \ Network \ Response)){main}
非常感谢任何帮助
答案 0 :(得分:7)
问题:
问题是,对于'date'字段,CakePHP 3返回一个对象,而不是字符串:
'date' => object(Cake\I18n\FrozenDate) {
'time' => '1997-01-03T00:00:00+00:00',
'timezone' => 'UTC',
'fixedNowTime' => false
},
尝试将其用作密钥不起作用,并抛出您所看到的错误。
如何处理:
每this area in the CakePHP book,为了适应这种情况,你可以:
使用闭包来访问列表中的实体mutator方法。
TLDR执行此操作:
$query = $articles->find('list', [
'keyField' => function ($e) {
return $e->date->format('Y-m-d');
},
'valueField' => 'title'
]);
有关其工作原理的说明:
基本上,它将每个实体的值(在您的情况下为每篇文章)放入变量$e
,并允许您使用/修改它的数据,并返回您想要用作键的字符串(或价值)领域。在上面的例子中,它获取date
对象,并在将其格式化为字符串之后再将其用作键。
答案 1 :(得分:1)
我尝试了一个类似的例子,我得到了同样的错误。
查看错误堆栈似乎与cake返回Time对象而不是字符串这一事实有关。
我找到了一种解决方法:您可以在实体中创建虚拟字段
瞻礼实体
protected function _getFormattedDate()
{
if(isset($this->date))
return $this->date->format('Y-m-d');
return null;
}
所以你可以做到
$holidays = $holidays->find('list',[
'keyField' => 'formatted_date',
'valueField'=>'name',
])->toArray();
您还可以使用Dave的建议来创建自定义查找程序。
<强> HolidaysTable 强>
public function findDate(Query $query, array $options)
{
$options['keyField'] = function ($e) {
if(isset($e->date))
return $e->date->format('Y-m-d');
return null;
};
$options['valueField'] = 'name';
return $this->findList($query, $options);
}
我刚刚添加了一个关于是否设置了日期字段的控件,否则你可能会收到错误。
<强>控制器强>
$holidays->find('date')->toArray();