我使用列表从模型中获取数据,它在中运行良好
这个例子来自Cakephp文档
$query = $articles->find('list', [
'keyField' => 'slug',
'valueField' => 'title'
]);
$data = $query->toArray();
我有一张名为假日的桌子
id[int]| date[date]| name[varchar(200)]| created[datetime]
所以想要一个以日期为关键字、以假日为值的列表像这样的
[
'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从date改为name时,效果非常好。
这是的日志
2016-04-29 04:26:41错误:〔InvalidArgumentException〕偏移量非法type请求URL:/sfworxerp/api/atteances/getMonthAttendanceData堆栈跟踪:F: ''public_html''sfworxerp''vendor''cakehp''cakehp''src''Collection''Iterator''MapReduce.php(160):Cake''Collection''Iterator''MapReduce::emit()F: ''public_html''sfworxerp''vendor''cakehp''cakehp''src''CollectionTrait.php(386):Cake''Collection''Iterator''MapReduce->emit("新年",对象(Cake''I18n''FrozenDate))F: ''public_html''sfworxerp''vendor''cakehp''cakehp''src''Collection''Iterator''MapReduce.php(177):Cake''ORM''ResultSet->Cake''Collection{closure}(对象(App''Model''Entity''Holiday),0,对象(Cake''Collection''Iterator''MapReduce)F: ''public_html''sfworxerp''vendor''cakehp''cakehp''src''Collection''Iterator''MapReduce.php(132):Cake''Collection''Iterator''MapReduce->_execute()[内部函数]:Cake''Collection''Iterator''MapReduce->getIterator()F: ''public_html''sfworxerp''vendor''cakehp''cakehp''src''Collection.php(50):IteratorIterator->__construct(对象(Cake''Collection''Iterator''MapReduce))F: ''public_html''sfworxerp''vendor''cakehp''cakehp''src''CollectionTrait.php(405):Cake''Collection''Collection->__construct(对象(Cake''Cllection''Iterator''MapReduce))F: ''public_html''sfworxerp''vendor''cakehp''cakehp''src''ORM''Table.php(1062):Cake''ORM''ResultSet->组合("日期"、"名称"、NULL)F: ''public_html''sfworxerp''vendor''cakehp''cakehp''src''Datasource''QueryTrait.php(490):Cake''ORM''Table->Cake''ORM{closure}(对象(Cake''ORM''ResultSet))F: ''public_html''sfworxerp''vendor''cakehp''cakehp''src''ORM''Query.php(1141):Cake''ORM''Query->_applyDecorators(对象(Cake''ORM''ResultSet))F: ''public_html''sfworxerp''vendor''cakehp''cakehp''src''Datasource''QueryTrait.php(272):Cake''ORM''Query->_decorateResults(对象(Cake''ORM''ResultSet))F: ''public_html''sfworxerp''vendor''cakehp''cakehp''src''ORM''Query.php(871):Cake''ORM''Query->_all()F: ''public_html''sfworxerp''vendor''cakehp''cakehp''src''Datasource''QueryTrait.php(288):Cake''ORM''Query->all()F: ''public_html''sfworxerp''src''Controller''Api''AAttendancesController.php(133):Cake''ORM''Query->toArray()[内部函数]:App''Controller''Api''AAttendancesController->getMonthAttendanceData()F: ''public_html''sfworxerp''vendor''cakehp''cakehp''src''Controller''Controller.php(429):call_user_func_array(数组,数组)F: ''public_html''sfworxerp''vendor''cakehp''cakehp''src''Routing''Dispatcher.php(114):Cake''Controller''Controller->invokeAction()F: ''public_html''sfworxerp''vendor''cakehp''cakehp''src''Routing''Dispatcher.php(87):Cake''Routing''Dispatcher->_invoke(对象(App''Controller''Api''AAttendancesController))F: ''public_html''sfworxerp''webroot''index.php(37):Cake''Routing''Dispatcher->dispatch(Object(Cake''Network''Request),对象(Cake''Network''Response)){main}
任何帮助都将不胜感激
问题:
问题是,对于"日期"字段,CakePHP 3返回一个对象,而不是字符串:
'date' => object(Cake'I18n'FrozenDate) {
'time' => '1997-01-03T00:00:00+00:00',
'timezone' => 'UTC',
'fixedNowTime' => false
},
尝试将其用作密钥是不起作用的,并且会抛出您所看到的错误。
如何处理:
根据CakePHP书中的这个区域,为了适应这一点,你可以:
使用闭包访问列表查找中的实体赋值器方法。
TLDR执行此操作:
$query = $articles->find('list', [
'keyField' => function ($e) {
return $e->date->format('Y-m-d');
},
'valueField' => 'title'
]);
工作原理说明:
基本上,它将每个实体(在您的案例中是每篇文章)的值放入变量$e
中,并允许您使用/修改它的数据,并返回要用作键(或值)字段的字符串。在上面的例子中,它获取date
对象,并将其格式化为字符串,然后返回用作键。
我尝试了一个类似的例子,但我得到了相同的错误。
查看错误堆栈似乎与cake返回Time对象而不是字符串这一事实有关。
我找到了一个变通方法:你可以在你的实体中创建一个虚拟字段
Holyday实体
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的建议来创建一个自定义查找器。
假期表
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();