malith124/laravel-ardent

Laravel 10 的 Eloquent ORM 的自验证智能模型

1.0.8 2024-09-10 10:31 UTC

This package is auto-updated.

Last update: 2024-09-10 10:33:03 UTC


README

Latest Stable Version License Total Downloads Monthly Downloads Daily Downloads

Laravel 框架 5 的 Eloquent ORM 的自验证智能模型。

基于 Colby Rabideau 为 Laravel 3 编写的 Aware 包。

版权 (C) 2013-2015 Max Ehsan & Igor Santos

变更日志

访问我们的 发布列表。变更日志在那里创建 :)

安装

laravelbook/ardent 添加到 composer.json 中的需求(在徽章上查看我们的最新稳定版本!)

{
    "require": {
        "laravelbook/ardent": "3.*"
    }
}

使用 composer update 更新您的包或使用 composer install 安装。

您还可以使用 composer require laravelbook/ardent 添加包,稍后指定您想要的版本(目前,dev-master 是您的最佳选择)。

(自 1.1.0 版本以来)Laravel 之外的使用

如果您想将 Ardent 作为独立的 ORM 包使用,请在项目的启动文件中使用以下配置(根据您的数据库更改属性)

\LaravelArdent\Ardent\Ardent::configureAsExternal(array(
  'driver'    => 'mysql',
  'host'      => 'localhost',
  'port'      => 3306,
  'database'  => 'my_system',
  'username'  => 'myself',
  'password'  => 'h4ckr',
  'charset'   => 'utf8',
  'collation' => 'utf8_unicode_ci'
), 'en'); //English is the default messages language, may be left empty

文档

简介

您是否经常在构建的应用程序中重复创建相同的样板代码?这段典型的表单处理代码是否看起来太熟悉了?

Route::post('register', function() {
        $rules = array(
            'name'                  => 'required|between:3,80|alpha_dash',
            'email'                 => 'required|between:5,64|email|unique:users',
            'password'              => 'required|min:6|confirmed',
            'password_confirmation' => 'required|min:6'
        );

        $validator = Validator::make(Input::all(), $rules);

        if ($validator->passes()) {
            User::create(array(
                    'name'     => Input::get('name'),
                    'email'    => Input::get('email'),
                    'password' => Hash::make(Input::get('password'))
                ));

            return Redirect::to('/')->with('message', 'Thanks for registering!');
        } else {
            return Redirect::to('/')->withErrors($validator->getMessages());
        }
    }
);

自行实现通常会导致大量重复的样板代码。作为额外的好处,您的控制器(或路由处理程序)会变得过于庞大,您的代码变得混乱、丑陋且难以理解。

如果有人为您做了所有繁重的工作呢?如果,而不是重复上面的混乱,您只需要输入这几行代码呢?...

Route::post('register', function() {
        $user = new User;
        if ($user->save()) {
            return Redirect::to('/')->with('message', 'Thanks for registering!');
        } else {
            return Redirect::to('/')->withErrors($user->errors());
        }
    }
);

欢迎来到 Ardent!

Ardent - 由魔法尘埃驱动的、手腕友好的、一站式解决方案,用于所有您单调乏味的输入清理样板代码!

玩笑话不说了,输入验证功能很快就会变得难以编写和维护。Ardent 通过提供帮助器来自动化许多重复性任务来处理这些复杂性。

尽管 Ardent 非常适合输入验证,但它还可以显著减少您的 Eloquent 数据模型代码。如果您发现自己一次又一次地在多个单独的应用程序中编写非常相似的代码,Ardent 特别有用。

例如,用户注册或博客文章提交是常见的编码要求,您可能希望在一个应用程序中实现并在其他应用程序中重用。使用 Ardent,您可以一次性编写您的 自我感知、智能 模型,然后在其他项目中重用它们(无需或仅进行很少的修改)。一旦您习惯了这种方式,您将真心想知道在没有 Ardent 的情况下您是如何应对的。

不再有重复的脑力劳动伤害了!

入门指南

Ardent 旨在扩展 Eloquent 基类,而不更改其核心功能。由于 Ardent 本身是 Illuminate\Database\Eloquent\Model 的后裔,因此所有您的 Ardent 模型都与 Eloquent 完全兼容,并可以充分利用 Laravel 框架强大的 OR/M 功能。

要创建一个新的Ardent模型,只需让您的模型类继承自Ardent基类。在接下来的示例中,我们将使用完整命名空间类来使示例更简洁,但您被鼓励在所有类中使用use

use LaravelArdent\Ardent\Ardent;

class User extends Ardent {}

注意:您可以自由地将您的Eloquent模型与Ardent的子类混合使用。如果一个模型对象不依赖于用户提交的内容,因此不需要验证,您可以保留Eloquent模型类不变。

Ardent 中的简单验证

Ardent模型使用Laravel的内置验证器类。为模型定义验证规则很简单,通常在模型类中作为静态变量完成。

class User extends \LaravelArdent\Ardent\Ardent {
  public static $rules = array(
    'name'                  => 'required|between:3,80|alpha_dash',
    'email'                 => 'required|between:5,64|email|unique:users',
    'password'              => 'required|min:6|confirmed',
    'password_confirmation' => 'required|min:6',
  );
}

注意:您也可以使用数组语法来指定验证规则。 我希望您不会介意旧Laravel文档的链接,但尽管Laravel文档很好,但不幸的是,从5.1版开始,关于验证规则管道/数组语法的清晰引用已经消失了。

Ardent模型在调用Ardent->save()时自动验证自身。

$user           = new User;
$user->name     = 'John doe';
$user->email    = 'john@doe.com';
$user->password = 'test';

$success = $user->save(); // returns false if model is invalid

注意:您也可以在任何时候使用Ardent->validate()方法来验证模型。

检索验证错误

当一个Ardent模型验证失败时,一个包含验证失败消息的Illuminate\Support\MessageBag对象被附加到Ardent对象上。

使用Ardent->errors()方法或Ardent->validationErrors属性检索验证错误消息集合实例。

使用Ardent->errors()->all()检索所有验证错误。使用Ardent->validationErrors->get('attribute')检索特定属性的错误。

注意:Ardent利用Laravel的MessagesBag对象,它有一个简单而优雅的错误格式化方法

覆盖验证

有两种方法可以覆盖Ardent的验证

1. 强制保存

forceSave()验证模型,但无论是否有验证错误都会保存。

2. 覆盖规则和消息

Ardent->save($rules, $customMessages)Ardent->validate($rules, $customMessages)都接受两个参数

  • $rules是一个与Ardent::$rules相同的表单的验证器规则数组。
  • 对于$customMessages参数也是如此(与Ardent::$customMessages相同)

一个非空的数组将仅覆盖类为该方法实例指定的规则或自定义错误消息。

注意:$rules$customMessages的默认值为空数组array();因此,如果您传递一个array(),则不会覆盖任何内容。

自定义验证错误消息

就像Laravel Validator一样,Ardent允许您使用相同的语法设置自定义错误消息。

class User extends \LaravelArdent\Ardent\Ardent {
  public static $customMessages = array(
    'required' => 'The :attribute field is required.',
    ...
  );
}

自定义验证规则

您可以像为Laravel Validator创建自定义验证规则一样创建自定义验证规则。

模型钩子(自2.0以来)

Ardent在Eloquent模型事件上提供了一些语法糖:传统模型钩子。这是将额外的操作连接到模型生命周期的不同时刻的简单方法。它们可用于在删除条目之前执行额外的清理工作,在验证发生后自动修复,或在更新发生后更新相关模型。

当返回false(特别是布尔值,而不是简单的“假”值)时,所有before钩子都会停止操作。因此,例如,如果您想在beforeSave方法中出现错误时停止保存,只需返回false,则不会发生保存,并且显然不会调用afterSave

以下是可用的完整钩子列表

  • before/afterCreate()
  • before/afterSave()
  • before/afterUpdate()
  • before/afterDelete()
  • before/afterValidate() - 当返回 false 时将停止验证,因此如果验证失败,则 save() 操作也将失败。

例如,您可以使用 beforeSave 来散列用户密码(实际上,使用 自动散列 将是一个更好的选择!)

class User extends \LaravelArdent\Ardent\Ardent {
  public function beforeSave() {
    // if there's a new password, hash it
    if($this->isDirty('password')) {
      $this->password = Hash::make($this->password);
    }
    
    return true;
    //or don't return nothing, since only a boolean false will halt the operation
  }
}

额外的 beforeSave 和 afterSave(自 1.0 版起)

beforeSaveafterSave 可以在运行时包含。只需将模型作为参数传递给 save()(或 forceSave())方法中的闭包。

$user->save(array(), array(), array(),
  function ($model) { // closure for beforeSave
    echo "saving the model object...";
    return true;
  },
  function ($model) { // closure for afterSave
    echo "done!";
  }
);

注意:闭包应有一个参数,因为它将传递正在保存的模型的引用。

更简洁的关系定义(自 2.0

您是否曾经编写了一个具有许多关系的 Eloquent 模型,只是注意到您的类是多么杂乱,所有这些几乎与方法名本身内容相同的单行代码?

在 Ardent 中,您可以在一个数组中以它们的信息定义您的关系,它们将像您在方法中定义它们一样工作。以下是一个示例

class User extends \LaravelArdent\Ardent\Ardent {
  public static $relationsData = array(
    'address' => array(self::HAS_ONE, 'Address'),
    'orders'  => array(self::HAS_MANY, 'Order'),
    'groups'  => array(self::BELONGS_TO_MANY, 'Group', 'table' => 'groups_have_users')
  );
}

$user = User::find($id);
echo "{$user->address->street}, {$user->address->city} - {$user->address->state}";

数组语法如下

  • 第一个索引值:关系名称,可以是以下之一 hasOnehasManybelongsTobelongsToManymorphTomorphOnemorphMany,或者相关的常量(例如 Ardent::HAS_MANYArdent::MORPH_ONE)。
  • 第二个索引值:类名,具有完整的命名空间。对于 morphTo 关系,不需要额外的参数。
  • 命名参数,遵循为原始 Eloquent 方法定义的参数
    • foreignKey [可选],对 hasOnehasManybelongsTobelongsToMany 有效
    • tableotherKey [可选]、timestamps [布尔值,可选] 和 pivotKeys [数组,可选],对 belongsToMany 有效
    • nametypeid,由 morphTomorphOnemorphMany 使用(后两个需要定义 name

注意:此功能基于易于 在 Yii 1.1 ActiveRecord 中声明关系

自动填充 Ardent 实体

Ardent 可以自动从表单输入提交中填充您的实体模型类!

让我们看看它是如何工作的。考虑以下代码片段

$user           = new User;
$user->name     = Input::get('name');
$user->email    = Input::get('email');
$user->password = Hash::make(Input::get('password'));
$user->save();

让我们调用 Ardent 的 魔法 并重写前面的代码片段

$user = new User;
$user->save();

就是这样!我们只是删除了无聊的东西。

信不信由你,上面的代码实际上执行的任务与它的较旧、但相当冗长的兄弟任务基本相同。Ardent 使用用户提交的表单数据填充模型对象的属性。不再需要费劲地查找您忘记填充的 Eloquent 属性。让 Ardent 负责无聊的事情,而您则专注于有趣的事情!
它遵循相同的 批量赋值规则,这取决于 $fillable/$guarded 属性。

要启用自动水分化功能,只需将模型类中的$autoHydrateEntityFromInput实例变量设置为true。然而,为了避免填充已存在的属性,如果您希望更新场景也进行自动水分化,则应使用$forceEntityHydrationFromInput

class User extends \LaravelArdent\Ardent\Ardent {
  public $autoHydrateEntityFromInput = true;    // hydrates on new entries' validation
  public $forceEntityHydrationFromInput = true; // hydrates whenever validation is called
}

自动清除冗余表单数据

Ardent模型可以神奇地清除冗余输入数据(如密码确认、隐藏的CSRF_token或自定义HTTP_method字段),以确保额外数据永远不会保存到数据库。Ardent将使用确认字段来验证表单输入,然后在将模型实例保存到数据库之前谨慎地丢弃这些属性!

要启用此功能,只需在模型类中将$autoPurgeRedundantAttributes实例变量设置为true

class User extends \LaravelArdent\Ardent\Ardent {
  public $autoPurgeRedundantAttributes = true;
}

您还可以清除其他字段。属性Ardent::$purgeFilters是一个闭包数组,您可以为它添加自定义规则。这些闭包接收属性键作为参数,并且应该为应该被清除的属性返回false。例如

function __construct($attributes = array()) {
  parent::__construct($attributes);

  $this->purgeFilters[] = function($key) {
    $purge = array('tempData', 'myAttribute');
    return ! in_array($key, $purge);
  };
}

自动转换安全文本属性

假设您的模型类中有一个名为password的属性,但不想将纯文本版本存储在数据库中。务实的方法是存储原始内容的哈希。不用担心,Ardent完全能够自动为您转换任意数量的安全字段!

为此,请在模型类中将属性名添加到Ardent::$passwordAttributes静态数组变量中,并将$autoHashPasswordAttributes实例变量设置为true

class User extends \LaravelArdent\Ardent\Ardent {
  public static $passwordAttributes  = array('password');
  public $autoHashPasswordAttributes = true;
}

Ardent将自动将纯文本密码属性替换为安全的哈希校验和并将其保存到数据库。它使用Laravel的Hash::make()方法内部生成哈希。 注意:建议使用Eloquent的$hidden属性来隐藏密码,即使已加密,在构建API或类似应用时也不会轻易泄露

如果您独立使用Ardent,可以使用Ardent::$hasher来验证字段值,例如使用User::$hasher->check($given_password, $user->password)

具有唯一规则的更新

Ardent可以帮助您处理唯一更新。根据Laravel文档,当您更新(因此验证)具有唯一规则的字段时,必须传递记录的唯一ID。如果不传递此ID,验证将失败,因为Laravel的验证器会认为这条记录是重复的。

来自Laravel文档

    'email' => 'unique:users,email,10'

过去,程序员必须手动管理ID的传递和规则集的改变以包括ID的实时运行。Ardent不是这样。只需设置带有unique的规则,调用函数updateUniques,Ardent将处理其余部分。

示例

在您扩展的模型中定义您的规则

  public static $rules = array(
     'email' => 'required|email|unique',
     'password' => 'required|between:4,20|confirmed',
     'password_confirmation' => 'between:4,20',
  );

在您的控制器中,当您需要更新时,只需调用

$model->updateUniques();

如果需要,您可以在运行时将规则传递给updateUniques,否则它将使用模型提供的静态规则。

注意,在上面的规则示例中,我们没有告诉验证器使用哪个表或字段,就像Laravel文档中描述的那样(即unique:users,email,10)。Ardent足够聪明,可以自己弄清楚。(感谢github用户@Sylph)