编辑:这是在从CakePHP 4.0升级到4.3之后
打开DebugKit后,CakePHP将引发以下错误消息:
Argument 1 passed to Cake\ORM\Entity::get() must be of the type string, bool given, called in /Users/thomasbelknap/one-vision/vendor/cakephp/cakephp/src/Datasource/EntityTrait.php on line 607这似乎是数据库查询的返回数组中一个空的数字索引元素的结果。让我解释一下:
在我的系统中,一个用户有许多估计(也有手推车和订单,但更多关于这一点)。用户和估计表文件中的这两个子句证明了这一点:
$this->belongsTo('Users', [
'foreignKey' => 'user_id',
]);
::snip::
$this->hasMany('Estimates', [
'foreignKey' => 'user_id',
'dependent' => true,
]);我使用以下查询结构在“仪表板”页面上查询此信息:
$user = $this->Users->get($this->getRequest()->getSession()->read('Auth.id'), [
'contain' => [
'UserGroups',
'Carts' => function ($q) {
return $q->limit(5);
},
'Orders' => function ($q) {
return $q->limit(5);
},
'Orders.OrderStatuses',
'Estimates' => function ($q) {
return $q->limit(5);
},
'Estimates.EstimateStatuses',
],
]);我不会对数据做任何进一步的转换。这里没有使用集合功能。然而,在返回的估计数中,总是有一个神秘的、数字索引的和空数组元素:
[1] => Visualize\Model\Entity\Estimate Object
(
[id] => 30
[user_id] => 1
[estimate_status_id] => 5
[estimate_po] => lksjdf
[estimate_total] =>
[name] => Full throttle
[instore_date] => Cake\I18n\FrozenDate Object
(
[date] => 2022-12-31 00:00:00.000000
[timezone_type] => 3
[timezone] => EST
)
[notes] => Let's do this.
[created] => Cake\I18n\FrozenTime Object
(
[date] => 2022-04-19 13:20:39.000000
[timezone_type] => 3
[timezone] => EST
)
[modified] => Cake\I18n\FrozenTime Object
(
[date] => 2022-04-19 13:21:26.000000
[timezone_type] => 3
[timezone] => EST
)
[1] =>
[location_info] => Array
(
)
[[new]] =>
[[accessible]] => Array
(
[user_id] => 1
[estimate_status_id] => 1
[estimate_po] => 1
[estimate_total] => 1
[name] => 1
[instore_date] => 1
[notes] => 1
[created] => 1
[modified] => 1
[user] => 1
[line_items] => 1
[orders] => 1
[estimate_options] => 1
)
[[dirty]] => Array
(
)
[[original]] => Array
(
)
[[virtual]] => Array
(
[item_count] => 1
[box_count] => 1
[deliverable_count] => 1
[0] => location_info
[estimate_total] => 1
)
[[hasErrors]] =>
[[errors]] => Array
(
)
[[invalid]] => Array
(
)
[[repository]] => Estimates
)这个只影响查询的估计部分!其他两个元素没有这个神秘的索引。下面是CakePHP在查询时最终使用的内容,这似乎也很好:
SELECT
Estimates.id AS Estimates__id,
Estimates.user_id AS Estimates__user_id,
Estimates.estimate_status_id AS Estimates__estimate_status_id,
Estimates.estimate_po AS Estimates__estimate_po,
Estimates.estimate_total AS Estimates__estimate_total,
Estimates.name AS Estimates__name,
Estimates.instore_date AS Estimates__instore_date,
Estimates.notes AS Estimates__notes,
Estimates.created AS Estimates__created,
Estimates.modified AS Estimates__modified,
EstimateStatuses.id AS EstimateStatuses__id,
EstimateStatuses.name AS EstimateStatuses__name,
EstimateStatuses.description AS EstimateStatuses__description,
EstimateStatuses.created AS EstimateStatuses__created,
EstimateStatuses.modified AS EstimateStatuses__modified
FROM
estimates Estimates
LEFT JOIN estimate_statuses EstimateStatuses ON EstimateStatuses.id = Estimates.estimate_status_id
WHERE
Estimates.user_id in (1)
ORDER BY
Estimates.modified DESC
LIMIT
5由于明显的原因,我真的需要DebugKit来工作,但我不知道这个神秘元素是从哪里来的。对我来说一切都是对的?
编辑:添加我的估计实体的定义:
<?php
declare(strict_types=1);
namespace Visualize\Model\Entity;
use Cake\ORM\Entity;
/**
* Estimate Entity
*
* @property int $id
* @property int $user_id
* @property int|null $estimate_status_id
* @property string|null $estimate_po
* @property float|null $estimate_total
* @property string $name
* @property \Cake\I18n\FrozenDate $instore_date
* @property string $notes
* @property \Cake\I18n\FrozenTime $created
* @property \Cake\I18n\FrozenTime $modified
*
* @property \Visualize\Model\Entity\User $user
* @property \Visualize\Model\Entity\LineItem[] $line_items
* @property \Visualize\Model\Entity\Order[] $orders
* @property \Visualize\Model\Entity\EstimateOption[] $estimate_options
* @property float $item_count
* @property int $box_count
* @property array|\Cake\Collection\CollectionInterface|null $by_location
* @property int $deliverable_count
* @property array $location_info
* @property \Visualize\Model\Entity\EstimateStatus|null $estimate_status
* @property array|\Cake\Collection\CollectionInterface|null $by_deliverable
*/
class Estimate extends Entity
{
/**
* Fields that can be mass assigned using newEntity() or patchEntity().
*
* Note that when '*' is set to true, this allows all unspecified fields to
* be mass assigned. For security purposes, it is advised to set '*' to false
* (or remove it), and explicitly make individual fields accessible as needed.
*
* @var array
*/
protected $_accessible = [
'user_id' => true,
'estimate_status_id' => true,
'estimate_po' => true,
'estimate_total' => true,
'name' => true,
'instore_date' => true,
'notes' => true,
'created' => true,
'modified' => true,
'user' => true,
'line_items' => true,
'orders' => true,
'estimate_options' => true,
];
/**
* @var array
*/
protected $_virtual = [
'item_count' => true,
'box_count' => true,
'deliverable_count' => true,
'location_info' => true,
'estimate_total' => true,
];
/**
* Returns a zero-filled version of the cannonical ID
*
* @param int $id The autoincremental ID
* @return string
*/
protected function _getId($id): string
{
return sprintf('%05d', $id);
}
/**
* Returns the sum of quantities of all line items.
*
* @return float
*/
protected function _getItemCount(): float
{
$count = 0;
if (!empty($this->line_items)) {
$collection = new \Cake\Collection\Collection($this->line_items);
$count = $collection->sumOf('quantity');
}
return (float)$count;
}
/**
* Returns the count of locations in the estimate
*
* @return int
*/
protected function _getBoxCount(): int
{
$count = 0;
if (!empty($this->line_items)) {
$collection = new \Cake\Collection\Collection($this->line_items);
$collection = $collection->combine('location_id', 'id');
$count = $collection->count();
}
return $count;
}
/**
* Returns the total number of deliverable types in the order.
*
* @return int
*/
protected function _getDeliverableCount(): int
{
$count = 0;
if (!empty($this->line_items)) {
$collection = new \Cake\Collection\Collection($this->line_items);
$collection = $collection->combine('deliverable_id', 'id');
$count = $collection->count();
}
return $count;
}
/**
* Returns the list of locations for this estimate
*
* @return array
*/
protected function _getLocationInfo(): array
{
$info = [];
if (!empty($this->line_items)) {
$collection = new \Cake\Collection\Collection($this->line_items);
$info = $collection->combine(
'location_id',
function ($entity) {
return $entity->location;
}
);
return $info->toArray();
}
return $info;
}
/**
* Returns either the name or the id of the given estimate
*
* @return string
*/
protected function _getName(): string
{
return $this->name ?? (string)$this->id;
}
public const FIELD_ID = 'id';
public const FIELD_USER_ID = 'user_id';
public const FIELD_ESTIMATE_STATUS_ID = 'estimate_status_id';
public const FIELD_ESTIMATE_PO = 'estimate_po';
public const FIELD_ESTIMATE_TOTAL = 'estimate_total';
public const FIELD_NAME = 'name';
public const FIELD_INSTORE_DATE = 'instore_date';
public const FIELD_NOTES = 'notes';
public const FIELD_CREATED = 'created';
public const FIELD_MODIFIED = 'modified';
public const FIELD_USER = 'user';
public const FIELD_LINE_ITEMS = 'line_items';
public const FIELD_ORDERS = 'orders';
public const FIELD_ESTIMATE_OPTIONS = 'estimate_options';
public const FIELD_ITEM_COUNT = 'item_count';
public const FIELD_BOX_COUNT = 'box_count';
public const FIELD_BY_LOCATION = 'by_location';
public const FIELD_DELIVERABLE_COUNT = 'deliverable_count';
public const FIELD_LOCATION_INFO = 'location_info';
public const FIELD_ESTIMATE_STATUS = 'estimate_status';
public const FIELD_BY_DELIVERABLE = 'by_deliverable';
}发布于 2022-05-16 19:31:28
仔细查看实体的转储,该字段显然被配置为一个,而查看其他公开的字段,它们似乎配置错误,因为该属性应该包含一个平面字符串数组,而不是像'item_count' => 1这样的字符串索引条目,因为该值声明字段名,因此您可以看到一个名为1的字段。
您也误解了输出,location_info不属于1字段,这实际上是两个不同的字段,1保存一些PHP不打印的空ish,比如null或false,以及location_info保存空数组。
使用debug()而不是pr()/print_r()来获得更好的结构化转储,该转储还正确地显示空数据。然后检查您的Estimate实体类(或任何可以动态配置的东西),并修复虚拟字段。
https://stackoverflow.com/questions/72263344
复制相似问题