首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >DebugKit错误:关联中的CakePHP get()神秘空元素

问DebugKit错误:关联中的CakePHP get()神秘空元素
EN

Stack Overflow用户
提问于 2022-05-16 17:34:16
回答 1查看 35关注 0票数 0

编辑:这是在从CakePHP 4.0升级到4.3之后

打开DebugKit后,CakePHP将引发以下错误消息:

代码语言:javascript
复制
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

这似乎是数据库查询的返回数组中一个空的数字索引元素的结果。让我解释一下:

在我的系统中,一个用户有许多估计(也有手推车和订单,但更多关于这一点)。用户和估计表文件中的这两个子句证明了这一点:

代码语言:javascript
复制
$this->belongsTo('Users', [
   'foreignKey' => 'user_id',
]);
::snip::
$this->hasMany('Estimates', [
   'foreignKey' => 'user_id',
   'dependent' => true,
]);

我使用以下查询结构在“仪表板”页面上查询此信息:

代码语言:javascript
复制
$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',
    ],
]);

我不会对数据做任何进一步的转换。这里没有使用集合功能。然而,在返回的估计数中,总是有一个神秘的、数字索引的和空数组元素:

代码语言:javascript
复制
[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在查询时最终使用的内容,这似乎也很好:

代码语言:javascript
复制
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来工作,但我不知道这个神秘元素是从哪里来的。对我来说一切都是对的?

编辑:添加我的估计实体的定义:

代码语言:javascript
复制
<?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';
}
EN

回答 1

Stack Overflow用户

发布于 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实体类(或任何可以动态配置的东西),并修复虚拟字段。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72263344

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档