在 CodeIgniter 4 中隐藏模型中的属性

Hiding attributes in model in CodeIgniter 4

我有一个 CodeIgniter 4 模型。
当我使用 find()/findAll() return 从它获取数据时,它 return 是模型中存在的所有属性。

$userModel->findAll();

我想隐藏其中一些,例如,我不想 return 日期 (created_at、updated_at)。

我试图创建一个实体对象并 return 它,但它也 return 包含所有内容。

基本上我想要做的是拥有像 Laravel 中那样的功能,其中您在模型中有一个 $hidden 保护数组。

我一直在试验 afterFind 回调,但我不喜欢这个解决方案。主要是因为使用 find()findAll()

时 $data 数组存在差异
protected $afterFind = ['prepareOutput'];

protected function prepareOutput(array $data) {
    return $data;
}

$data['data']是使用find()
时的实际数据 $data['data']是使用findAll()时的数组数组;
这有点道理,但我必须确保根据使用的方法修改数据。

我在文档中遗漏了什么吗?可以用更简单的方式完成吗?

所以我想到了这个,但我仍然愿意接受更好更好的解决方案。

首先我创建了自己的模型并添加了隐藏一些属性的逻辑:

<?php

namespace App\Models;

use CodeIgniter\Model;

class MyBaseModel extends Model {

    protected $hidden = [];

    public function prepareOutput(array $data) {

        // if the hidden array is empty, we just return the original dta
        if (sizeof($this->hidden) == 0) return $data;

        // if no data was found we return the original data to ensure the right structure
        if (!$data['data']) return $data;

        $resultData = [];

        // We want the found data to be an array, so we can loop through it.
        // find() and first() return only one data item, not an array
        if (($data['method'] == 'find') || ($data['method'] == 'first')) {
            $data['data'] = [$data['data']];
        }

        if ($data['data']) {
            foreach ($data['data'] as $dataItem) {
                foreach ($this->hidden as $attributeToHide) {
                    // here we hide the unwanted attributes, but we need to check if the return type of the model is an array or an object/entity
                    if (is_array($dataItem)) {
                        unset($dataItem[$attributeToHide]);
                    } else {
                        unset($dataItem->{$attributeToHide});
                    }
                }
                array_push($resultData, $dataItem);
            }
        }

        // return the right data structure depending on the method used
        if (($data['method'] == 'find') || ($data['method'] == 'first')) {
            return ['data' => $resultData[0]];
        } else {
            return ['data' => $resultData];
        }

    }

}

现在我可以扩展我现有的模型并填写我想隐藏的属性:

<?php namespace App\Models;
    
use App\Entities\User;

class UserModel extends MyBaseModel {

    protected $table = 'users';
    protected $primaryKey = 'id';

    protected $returnType = User::class;
    protected $useSoftDeletes = false;

    protected $allowedFields = ['email', 'password', 'first_name', 'last_name'];

    protected $useTimestamps = true;
    protected $createdField = 'created_at';
    protected $updatedField = 'updated_at';

    protected $allowCallbacks = true;
    protected $afterFind = ['prepareOutput'];
    protected $hidden = ['created_at', 'updated_at'];

}