当我使用 eloquent 时,我可以使用“where”方法,然后使用“get”方法来填充包含我在数据库中选择的对象的对象。我是说:
$users = User::where('gender', 'M')->where('is_active', 1)->get(['pseudo', 'email', 'age', 'created_at'])->toArray();
在这里,我可以选择我想要的列,例如“伪”、“电子邮件”等。但我在 laravel doc 中错过的是相反的方法。它可能是这样的:
$users = User::where('gender', 'M')->where('is_active', 1)->notGet(['pseudo', 'email', 'age', 'created_at'])->toArray();
感谢您对未来的回答,祝您有美好的一天。
如果您只需要从模型的数组或 JSON 表示中隐藏属性,您可以使用一种或两种方法:
将 $hidden 属性添加到您的模型类 User extends Model { /** * 应该为数组隐藏的属性。 */ 保护 $hidden = ['密码']; }
使用 makeHidden 函数 $users = $users->makeHidden(['address', 'phone_number']);
有关更多详细信息,请参阅其他答案...但有时您不想将大量数据(地理空间、html、日志...)加载到您的应用程序中,它会很慢并且占用更多内存。 OP 要求 SQL 查询因此我的回答,但大多数时候只隐藏 JSON 响应中的数据更方便。
AFAIK SQL 中没有内置选项来显式排除列,因此 Laravel 不能这样做。但是你可以试试this trick
更新
另一个技巧是指定模型中的所有列(或使用额外查询从 this answer 使用 $this->getTableColumns()
获取所有列,也可以在每次迁移后缓存以避免两次查询)然后添加 local scope 函数
// The below code requires you to define all columns in $columns.
// A better approach is to query the schema of the table and cache it after each
// migration, for more details: https://stackoverflow.com/a/56425794/3192276
protected $columns = ['id','pseudo','email'];
public function scopeExclude($query, $value = [])
{
return $query->select(array_diff($this->columns, (array) $value));
}
然后你可以这样做:
$users = User::where('gender', 'M')
->where('is_active', 1)
->exclude(['pseudo', 'email', 'age', 'created_at'])
->toArray();
在模型中使用 hidden
数组很好,但如果您不想一直隐藏您的列并使用 makeVisible
来访问它们,那么请改为隐藏您的列以防止序列化您需要像这样的 makeHidden
功能:
$res = Model::where('your query')->get();
$res->makeHidden(['column_one','column_two','column_n']);
return response()->json($res);
except
在我的查询中调用它。
created_at
、updated_at
、deleted_at
,这个答案对我来说是最完美的。
Model::first()->relationship->makeHidden(['field1', 'field2']);
一样对它们进行序列化
我不知道以前的 Laravel 版本,但在 5.4 中,您可以将这一行放在 User 模型中
protected $hidden = ['pseudo', 'email', 'age', 'created_at'];
然后 User::find(1);
将返回除 pseudo
、email
、age
和 created_at
之外的所有字段。
但是您仍然可以使用以下方法检索这些隐藏字段:
$user = User::find(1);
$email = $user['email']; // or $user->email;
description
列,只有在加载单个模型时才需要,但在加载所有模型时不需要。跳过它可以节省大量内存。
我已经查看了@Razor 的答案
但是通过跳过 $columns 属性有一种非常方便的方式
/**
* Scope a query to only exclude specific Columns.
*
* @author Manojkiran.A <manojkiran10031998@gmail.com>
* @param \Illuminate\Database\Eloquent\Builder $query
* @return \Illuminate\Database\Eloquent\Builder
*/
public function scopeExclude($query, ...$columns)
{
if ($columns !== []) {
if (count($columns) !== count($columns, COUNT_RECURSIVE)) {
$columns = iterator_to_array(new \RecursiveIteratorIterator(new \RecursiveArrayIterator($columns)));
}
return $query->select(array_diff($this->getTableColumns(), $columns));
}
return $query;
}
/**
* Shows All the columns of the Corresponding Table of Model
*
* @author Manojkiran.A <manojkiran10031998@gmail.com>
* If You need to get all the Columns of the Model Table.
* Useful while including the columns in search
* @return array
**/
public function getTableColumns()
{
return \Illuminate\Support\Facades\Cache::rememberForever('MigrMod:' . filemtime(database_path('migrations')), function () {
return $this->getConnection()->getSchemaBuilder()->getColumnListing($this->getTable());
});
}
getTableColumns
函数将获取表的所有列,因此您无需定义 $column
属性
注意:表的列名将被缓存,直到添加或删除迁移目录的内容。
修改迁移目录中的文件内容不会重新缓存列
要手动清除缓存,您可以运行 php artisan cache:clear
您可以像这样使用 hidden
数组:
class Promotion extends Model
{
protected $table = 'promotion';
protected $hidden = array('id');
}
我们从包含所有字段的模型中获取 eloquent 对象,将其转换为数组,然后将其放入集合中。比我们得到除了数组 $fields 中指定的所有字段之外的所有字段。
$fields = ['a', 'b', 'c', 'N'];
$object = Model::find($id);
return collect($object->toArray())->except($fields);
更清楚地,让我们举个例子:
// Array of fields you want to remove
$fields_to_remove = ['age', 'birthday', 'address'];
// Get the result of database
$user = User::find($id);
// Transform user object to array
$user = $user->toArray();
// Create a collection with the user inside
$collection = collect($user);
// Get all fields of our collection except these fields we don't want
$result = $collection->except($fields_to_remove);
// Return
return $result;
上面的这个例子和第一个例子完全一样,但解释得更多。
我有一个对我有用的解决方案,它与已经说明的略有不同。
解决方案:
$all_columns = Schema::getColumnListing('TABLE_NAME');
$exclude_columns = ['COLUMN_TO_EXCLUDE_1', 'COLUMN_TO_EXCLUDE_2'];
$get_columns = array_diff($all_columns, $exclude_columns);
return User::select($get_columns)->get();
推理:
为了我:
Razor 的回答不起作用,因为我收到以下错误:
BadMethodCallException with message 'Call to undefined method App/CaseStudy::exclude()'
然后,剩下的答案试图隐藏模型中的列。不幸的是,这会为我班级中的每个方法隐藏它们,这不是我想要的。
因此,最后,我修改了 Razor 的解决方案,使其无需隐藏每种方法的任何列即可工作。
我希望这可以帮助别人! 😊
您可以像这样使用 makeHidden
数组:(在 get() 或 all() 之后)
$users = User::where('gender', 'M')->where('is_active', 1)->get()->makeHidden(['pseudo', 'email', 'age', 'created_at '])->toArray();
您可以利用 Illuminate\Support\Facades\Schema::getColumnListing('table_name');
use Illuminate\Support\Facades\Schema;
$users_table_columns = Schema::getColumnListing('users');
$exclude_columns = [
'password',
'token',
'address',
];
$select = array_diff($users_table_columns, (array) $exclude_columns);
$site = User::select($select)
->where('gender', 'M')
->where('is_active', 1)
->first();
您可以使用未设置的 unset($category->created_at,$category->updated_at);
$fcategory = array();
$kCategory = KCategory::where("enabled", true)->get();
foreach ($kCategory as $category) {
$subkCategory = PostCategory::select("id", "name", "desc")
->where("id_kcategory", $category->id)
->where("enabled", true)
->get();
unset($category->created_at, $category->updated_at);
$fcategory[] = $category;
}
"laravel/lumen-framework": "5.7.8"
对我有用
scopeExclude()
就是这样调用的。在 laravel.com/docs/5.3/eloquent#local-scopes 上阅读有关 laravel 范围的信息Schema::getColumnListing('table')
的结果并在每次迁移时清除它,即避免额外的 SQL 查询的方式。