zoha/laravel-meta

用于处理模型元数据的包

安装次数: 63,667

依赖: 1

建议者: 0

安全: 0

星标: 208

关注者: 5

分支: 28

开放性问题: 3

类型:

v2.0.2 2024-03-31 14:12 UTC

This package is auto-updated.

Last update: 2024-08-31 00:43:57 UTC


README

一个用于处理元数据的 Laravel 包!

Package Image

Zoha - laravel-meta stars - laravel-meta forks - laravel-meta GitHub tag License

页面内容

  1. 简介
  2. 特性
  3. 安装
  4. 基本方法
  5. 子句
  6. 其他方法和特性
  7. 许可证
  8. 贡献

简介

gif-file

有时我们的 Laravel 模型需要很多信息,这些信息应该存储在数据库中。例如,假设你想创建一个博客,并为这个博客添加一个帖子模型。这个模型最需要的信息是标题和内容。但这个模型可能还有更多信息,比如点赞数、下载链接、缩略图、浏览次数等。当这些信息量很大时,我们需要为模型表创建更多的列,如果列太多,会很难处理。此外,每篇帖子可能都有其他帖子不需要的独特信息。在这种情况下,这个包会很有帮助。如果我们想简单地解释这个包:Laravel Meta 允许你为每个模型存储信息,并轻松访问它们,而不必在数据库表中为这些信息创建新列。如果你还没有注意到,请看下面的例子。

特性

  • 轻松存储和获取每个模型的元数据
  • 在数据库表中创建许多列的替代方案
  • 最少的查询次数和完全优化
  • 能够通过元数据过滤数据库记录

安装

首先,使用 composer 安装此包

 $ composer require zoha/laravel-meta

如果你使用 Laravel <= 5.4,请将 ServiceProvider 和 Alias 添加到 config/app.php 中

'providers' => [
    ...
    Zoha\Meta\MetaServiceProvider::class,
    ...
]
'aliases' => [
    ...
    'Meta' => Zoha\Meta\Facades\MetaFacade::class,
    ...
]

然后执行迁移命令以迁移元数据表

 $ php artisan migrate

然后,为了将元数据功能添加到你的每个模型中,你只需将其从 MetableModel 继承,而不是从 Model 继承。

use Zoha\MetableModel;

class Post extends MetableModel
{
    ...
}

或者你可以使用 Metable 特性

use Zoha\Metable;

class Post extends Model
{
    use Metable;
    ...
}
可选部分

你可以使用此命令发布元数据配置文件

 $ php artisan vendor:publish --provider="Zoha\Meta\MetaServiceProvider" --tag=config

在此文件中,你可以更改默认的元数据表(默认:meta)或者你可以 为特定模型自定义元数据表

就这样!现在你可以使用所有的 Laravel 元数据功能了

在下面的所有示例中,我们假设 $post 已设置为 Post::first(),其中 Post 模型是一个示例模型

基本方法

创建新元数据

要创建元数据,你可以在模型上使用 createMeta

$post->createMeta('key' , 'value');

或者你可以这样创建多个元数据

$post->createMeta([
    'key1' => 'value1',
    'key2' => 'value2'
]);

@return : createMeta 方法如果元数据创建成功则返回 true,否则返回 false

addMeta 方法是 createMeta 方法的别名

更新元数据

要更新元数据,你可以在模型上使用 updateMeta

$post->updateMeta('key' , 'new value');

或者你可以这样更新多个元数据

$post->updateMeta([
    'key1' => 'new value 1',
    'key2' => 'new value 2'
]);

@return : 如果更新成功,updateMeta 返回 true。但如果元数据已不存在或更新失败,则返回 false

创建或更新元数据

要创建或更新元数据,请使用 setMeta 方法,此方法将更新元数据,如果尚未存在,则创建新的元数据

$post->setMeta('key' , 'value'); // create meta
$post->setMeta('key' , 'new value'); // update meta

或者您可以这样设置多个元数据

$post->setMeta([
    'key1' => 'value 1',
    'key2' => 'value 2'
]);

@return : setMeta 如果成功则返回 true。否则返回 false

或者,您可以使用 meta 属性 来设置元数据,如下所示

$post->meta->key1 = 'value';
$post->meta->key2 = 'value2';
$post->meta->save();

获取元数据

getMeta 方法将返回元数据的值

//return meta value or null if meta not exists
$post->getMeta('key');

// return value or 'default value ' if not exists or value is null
$post->getMeta('key' , 'default value') ;

您也可以使用 meta 属性 来获取元数据的值

$post->meta->key; // return meta value

获取元数据列表

getMetas 方法将返回所有元数据作为集合

// return a collection of all metas for this model
// no meta yet ? -> empty collection
$post->getMetas() ;

删除元数据

要删除元数据,请使用 deleteMeta 方法

$post->deleteMeta(); // delete all meta of this model

$post->deleteMeta('key'); // delete a specific meta

或者您可以使用 unsetMeta 方法代替,这两种方法都是相同的。 truncateMeta 也会删除特定模型的所有元数据

$post->truncateMeta(); // delete all model meta

检查元数据是否存在

如果您想检查是否存在特定的元数据,可以使用 hasMeta 方法(如果元数据存在但值为 null,则返回 false)

$post->hasMeta(); // return true if this model has at least one meta
$post->hasMeta('key'); // return true or false

第二个参数指定是否接受 null 值。如果您将第二个参数传递为 true,即使值为 null,如果元数据存在,则返回 true

$post->setMeta('key' , null); // set key to null
$post->hasMeta('key'); // return false
$post->hasMeta('key' , true); // return true

如果您想指定一个特定的帖子具有特定的元数据,即使其值为 null,也请使用 existsMeta 方法。

$post->setMeta('key' , null); // set key to null
$post->existsMeta('key'); // return true

增加元数据

您可以使用 increaseMeta 方法简单地增加元数据的值。请注意,增加浮点值时,除非指定,否则不会增加小数部分。

$post->setMeta('key' , 3);
$post->increaseMeta('key'); // meta value will change to 4

$post->setMeta('key' , 3.5);
$post->increaseMeta('key'); // meta value will change to 4.5

$post->setMeta('key' , 3.5);
$post->increaseMeta('key' , .1); // meta value will change to 3.6

$post->setMeta('key2' , 'not integer value');
$post->increaseMeta('key2'); // meta value will not change

您可以为确定增加步骤传递第二个参数

$post->setMeta('key' , 3);
$post->increaseMeta('key',3); // meta value will change to 6

减少元数据

您可以使用 decreaseMeta 方法简单地减少元数据的值。请注意,减少浮点值时,除非指定,否则不会减少小数值。

$post->setMeta('key' , 3);
$post->decreaseMeta('key'); // meta value will change to 2

$post->setMeta('key' , 3.5);
$post->decreaseMeta('key'); // meta value will change to 2.5

$post->setMeta('key' , 3.5);
$post->decreaseMeta('key', .1); // meta value will change to 3.4

$post->setMeta('key2' , 'not integer value');
$post->decreaseMeta('key2'); // meta value will not change

您也可以为确定减少步骤传递第二个参数

$post->setMeta('key' , 3);
$post->decreaseMeta('key',3); // meta value will change to 0

子句

Where Meta 子句

通过元数据值过滤项目

$result = Post::whereMeta('key','value');
// you can use operator :
$result = Post::whereMeta('key', '>' , 100);

// you can use multiple whereMeta Clause
$result = Post::whereMeta('key', '>' , 100)
                            ->whereMeta('key' , '<' , 200);
//orWhereMeta clause
$result = Post::whereMeta('key', '>' , 100)
                            ->orWhereMeta('key' , '<' , 50);
//branched clauses
$result = Post::where(function($query){
    $query->where(function($query){
        $query->whereMeta('key1' , 'value1');
        $query->orWhereMeta('key1' , 'value2');
    });
    $query->whereMeta('key2' , 'like' , '%value%');
    $query->WhereMeta('key3' , '>' , 100);
});

您也可以传递一个数组作为过滤结果

// all of below conditions will converted to 'AND'
$result = Post::whereMeta([
    'key1' => 'value1',
    [ 'key2' , '!=' , 'value2' ],
    [ 'key3' , 'value3' ]
]);

您还可以使用 orWhere 为多个 or where 子句

$result = Post::orWhereMeta([
    'key1' => 'value1',
    [ 'key2' , '!=' , 'value2' ],
    [ 'key3' , 'value3' ]
]);

您可以使用分支过滤器来处理所有元数据子句

Where Meta In 子句

whereMetaInwhereMetaNotIn 子句

$result = Post::whereMetaIn('key', ['value1' , 'value2']);
$result = Post::whereMetaNotIn('key', ['value1' , 'value2']);

// multiple clauses
$result = Post::whereMetaIn('key', [1,2])
                            ->whereMetaIn('key2' , [1,2]);

// 'orWhere' clauses
$result = Post::whereMetaNotIn('key', [1,2,3])
                            ->orWhereMetaIn('key2', [1,2])
                            ->orWhereMetaNotIn('key3', [1,2]);

Where Meta Between 子句

whereMetaBetweenwhereMetaNotBetween 子句

$result = Post::whereMetaBetween('key', [0,100]);
$result = Post::whereMetaNotBetween('key', [0,100]);

// multiple clauses
$result = Post::whereMetaBetween('key', [100,200])
                            ->whereMetaBetween('key2' , [100,200]);

// 'orWhere' clauses
$result = Post::whereMetaNotBetween('key', [1000,8000])
                            ->orWhereMetaBetween('key2', [1,5])
                            ->orWhereMetaNotBetween('key3', [0,100]);

Where Meta Null 子句

whereMetaNullwhereMetaNotNull 子句

$result = Post::whereMetaNull('key');
$result = Post::whereMetaNotNull('key');

// multiple clauses
$result = Post::whereMetaNull('key')
                            ->whereMetaNull('key2');

// 'orWhere' clauses
$result = Post::whereMetaNotNull('key')
                            ->orWhereMetaNull('key2')
                            ->orWhereMetaNotNull('key3');

Where Meta Has 子句

whereMetaHaswhereMetaDoesntHave 子句

//filter records that has at least one meta
$result = Post::whereMetaHas();

$result = Post::whereMetaHas('key');
$result = Post::whereMetaHas('key' , true); //count null values

$result = Post::whereMetaDoesntHave('key');
$result = Post::whereMetaDoesntHave('key' , true); //count null values

// multiple clauses
$result = Post::whereMetaHas('key')
                            ->whereMetaDoesntHave('key2');

// 'orWhere' clauses
$result = Post::whereMetaDoesntHave('key')
                            ->orWhereMetaHas('key2')
                            ->orWhereMetaDoesntHave('key3');

按元数据排序

您可以使用 orderByMeta 子句对数据库结果进行排序

Post::orderByMeta('price')->get();

Post::orderByMeta('price' , 'desc')->get();

Post::orderByMeta('price')->orderByMeta('likes' , 'desc')->get();

预加载

如果您第一次调用 $post->getMeta('key'),所有这个模型的元数据都将一次性加载(一次)。如果您尝试从这个模型获取另一个元数据,则不会执行另一个查询,元数据值将来自之前的查询。但是,如果您尝试从另一个模型获取元数据,则将为新模型执行另一个查询。如果您想在一个查询中获取所有模型的元数据,可以使用元数据的预加载。您只需调用 withMeta 范围,如下所示

$posts = Post::withMeta()->get(); // will return all posts results with their meta values

请注意,with('meta') 将不起作用

其他方法和特性

注意

  • 默认情况下,当您尝试获取它们时,所有集合、数组和 JSON 值都将转换为集合。
  • 所有 []"{}""[]"null 值都将被视为 null。
  • 如果元数据模型中的一个项目被删除,与该项目相关的所有元数据也将被删除。

数据类型

所有 setMetagetMetaupdateMetacreateMeta 方法都接受第三个参数,该参数确定元数据类型。以下是一些该功能的示例

可用的数据类型:stringintegerfloatnullcollectionjsonarrayboolean

setMeta 方法中

$post->setMeta('key' , '123' , 'integer');
$post->meta->key; // 123 ( integer )

$post->setMeta('key' , '123.45' , 'integer');
$post->meta->key; // 123 ( integer - decimal dropped)

$post->setMeta('key' , '123.45' , 'float');
$post->meta->key; // 123.45 ( float )
//----------------------------------
$post->setMeta('key' , [1,2,3] , 'json');
$post->meta->key; // "[1,2,3]" ( string - json )
//----------------------------------
$post->setMeta([
    'key1' => 'value',
    'key2' => 2
    'key3' => [1,2,3]
],'string' ); // all values will converted to string when you try to get them
$post->meta->key2; // "2" ( string )
$post->meta->key3; // "[1,2,3]" ( string json )

createMetaupdateMeta 方法中的第三个参数与 setMeta 方法中的相同

getMeta 方法中

$post->setMeta('key' , 123);
$post->getMeta('key' , 'null' , 'string'); // "123" (string)
//----------------------------------
$post->setMeta('key' , [1,2,3] , 'string');
$post->getMeta('key' , 'null'); // "[1,2,3]" (string)
$post->getMeta('key' , 'null' , 'array'); // [1,2,3] (array)
$post->getMeta('key' , 'null' , 'boolean'); // true (boolean)

自定义元数据表

默认情况下,所有模型的元数据都将存储在 meta 数据库表中。但如果您想,您可以为特定模型使用一个单独的表。

例如,您有 PostCommentUser 模型

您希望将所有帖子评论的元数据存储在默认表中,但用户的元数据标签存储在特殊表中。为此,您需要执行以下四个步骤

第一步:您应该使用以下命令发布包配置文件

$ php artisan vendor:publish --provider="Zoha\Meta\MetaServiceProvider" --tag=config

此命令将在您的配置文件夹中放置一个名为 meta.php 的文件

第二步:在 tables 数组中打开配置文件,您会找到一个自定义数组。在这个数组中,您可以添加新的表名。在我们的例子中,我们将 users_meta 添加到这个数组中以处理用户元数据

'tables' => [
    'default' => 'meta',
    'custom'  => [
        'users_meta'
    ],
]

第三步:您需要运行迁移命令来创建新表。

$ php artisan migrate

如果您已经迁移了元数据迁移,您应该回滚此迁移并再次迁移(以创建新表)

最后一步:现在新表已创建,您可以将它引入到 User 模型(或您想处理的任何模型)中,以便使用此表处理其元数据。如下所示

use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
    use \Zoha\Metable;

    protected $metaTable = 'users_meta';
}

元数据模型

您可以在项目中自由使用元数据模型

use Zoha\Meta\Models\Meta;
$count = Meta::count();

注意:如果您使用元数据模型(直接更改数据库)更改元数据值,则之前加载的元数据值将不会更新。如果您想更新它们,您应该调用 refreshLoadedMeta 方法

use Zoha\Meta\Models\Meta;

$post->meta->key1; // exmaple : return 'test'
Meta::truncate();
$post->meta->key1; // still return 'test'

$post->refreshLoadeMeta();
$post->meta->key1; // will return null

元数据表

元数据表的结构如下

Schema::create('meta', function (Blueprint $table) {
    $table->increments('id');
    $table->string('key',110);
    $table->text('value')->nullable();
    $table->string('type')->default(Meta::META_TYPE_STRING);
    $table->boolean('status')->default(true);
    $table->string('owner_type',80);
    $table->integer('owner_id');
    $table->unique(['key','owner_type','owner_id']);
    $table->timestamps();
});

许可证

License: MIT

贡献

该项目欢迎您的贡献 贡献