Laravel Framework 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
是您最好的选择)。
如果您想将 Ardent 用作独立的 ORM 包,我们邀请您在项目的引导/启动文件中使用以下配置(显然,根据您的数据库更改属性):
LaravelArdentArdentArdent::configureAsExternal(array( 'driver' => 'mysql', 'host' => 'localhost', 'port' => 3306, 'database' => 'my_system', 'username' => 'myself', '密码' => 'h4ckr', '字符集' => 'utf8', '排序规则' => 'utf8_unicode_ci'), 'en'); //默认消息语言为英语,可以留空
介绍
入门
使用 Ardent 轻松进行验证
检索验证错误
重写验证
自定义验证错误消息
自定义验证规则
模型挂钩
更清晰的关系定义
自动水合热心实体
自动清除冗余表单数据
自动转换安全文本属性
具有独特规则的更新
您是否经常发现自己在构建的应用程序中重新创建相同的样板代码?您是否觉得这个典型的表单处理代码非常熟悉?
路线::post('注册', function() {$rules = array('名称' => '必需|之间:3,80|alpha_dash','电子邮件' => '必需|之间:5,64|电子邮件|unique:users','password' => 'required|min:6|confirmed','password_confirmation' => 'required|min:6');$validator =验证器::make(输入::all(), $rules);if ($validator->passes()) { User::create(array('name' => Input::get('name'),'email' => Input::get('email'),'password' => Hash::make(Input::获取('密码')) ));return Redirect::to('/')->with('message', '感谢您注册!'); } else {return Redirect::to('/')->withErrors($validator->getMessages()); } } );
自己实现这一点通常会导致大量重复的样板代码。作为额外的好处,你的控制器(或路由处理程序)会过早地变得臃肿,并且你的代码会变得混乱、丑陋且难以理解。
如果其他人为你完成所有繁重的工作怎么办?如果您不需要重复上面的混乱,而只需要输入这几行怎么办?...
Route::post('register', function() {$user = new User;if ($user->save()) {return Redirect::to('/')->with('message', '谢谢进行注册!'); } else {return Redirect::to('/')->withErrors($user->errors()); } } );
输入热心!
Ardent - 魔法灰尘驱动、手腕友好的一站式解决方案,可解决您所有沉闷的输入消毒样板!
撇开双关语不谈,输入验证功能的编写和维护很快就会变得乏味。 Ardent 通过提供帮助来自动执行许多重复性任务来解决这些复杂性。
不过,Ardent 不仅适用于输入验证,它还可以帮助您显着减少 Eloquent 数据模型代码。如果您发现自己疲倦地在多个单独的应用程序中一次又一次地编写非常相似的代码,那么 Ardent 特别有用。
例如,用户注册或博客文章提交是一种常见的编码要求,您可能希望在一个应用程序中实现并在其他应用程序中再次重用。借助 Ardent,您只需编写一次具有自我意识的智能模型,然后在其他项目中重复使用它们(无需修改或只需很少的修改)。一旦你习惯了这种做事方式,你就会真诚地想知道如果没有 Ardent,你是如何应对的。
您不再遭受重复性脑劳损!
Ardent
目标是在不改变其核心功能的情况下扩展Eloquent
基类。由于Ardent
本身是IlluminateDatabaseEloquentModel
的后代,因此所有Ardent
模型都与Eloquent
完全兼容,并且可以充分利用 Laravels Awesome OR/M 的全部功能。
要创建新的 Ardent 模型,只需使模型类从Ardent
基类派生即可。在接下来的示例中,我们将使用完整的命名空间类来使示例更清晰,但鼓励您在所有类中使用use
:
使用 LaravelArdentArdentArdent;class User 扩展 Ardent {}
注意:您可以自由地将普通 Eloquent 模型与 Ardent 后代模型混合在一起。如果模型对象不依赖于用户提交的内容,因此不需要验证 - 您可以保留 Eloquent 模型类不变。
Ardent 模型使用 Laravel 的内置 Validator 类。为模型定义验证规则很简单,通常在模型类中作为静态变量完成:
class User extends LaravelArdentArdentArdent { public static $rules = array('name' => 'required| Between:3,80|alpha_dash','email' => 'required| Between:5,64|email|unique:users', '密码' => '必需|分钟:6|确认','password_confirmation' => '必需|分钟:6', ); }
注意:您也可以自由使用数组语法来验证规则。我希望您不介意旧的 Laravel 文档链接,但与 Laravel 文档一样,不幸的是,自 5.1 以来,验证规则的管道/数组语法的清晰参考已经消失。
当Ardent->save()
被调用时,Ardent 模型会自动验证自身。
$user = 新用户;$user->name = 'John doe';$user->email = '[email protected]';$user->password = 'test';$success = $user->save( ); // 如果模型无效则返回 false
注意:您还可以随时使用
Ardent->validate()
方法验证模型。
当 Ardent 模型验证失败时,会将IlluminateSupportMessageBag
对象附加到包含验证失败消息的 Ardent 对象。
使用Ardent->errors()
方法或Ardent->validationErrors
属性检索验证错误消息集合实例。
使用Ardent->errors()->all()
检索所有验证错误。使用Ardent->validationErrors->get('attribute')
检索特定属性的错误。
注意: Ardent 利用 Laravel 的 MessagesBag 对象,该对象具有简单而优雅的格式化错误方法。
有两种方法可以覆盖 Ardent 的验证:
forceSave()
验证模型,但无论是否存在验证错误都会保存。
Ardent->save($rules, $customMessages)
和Ardent->validate($rules, $customMessages)
都采用两个参数:
$rules
是与Ardent::$rules
形式相同的验证器规则数组。
$customMessages
参数也是如此(与Ardent::$customMessages
相同)
非空数组将覆盖类仅为该方法实例指定的规则或自定义错误消息。
注意:
$rules
和$customMessages
的默认值为空array()
;因此,如果您传递array()
则不会覆盖任何内容。
就像 Laravel 验证器一样,Ardent 允许您使用相同的语法设置自定义错误消息。
class User extends LaravelArdentArdentArdent { public static $customMessages = array('required' => ':attribute 字段是必需的。', ... ); }
您可以像创建 Laravel 验证器一样创建自定义验证规则。
Ardent 为 Eloquent 的模型事件提供了一些语法糖:传统模型挂钩。它们是一种将额外操作连接到模型生命中不同时刻的简单方法。它们可用于在删除条目之前执行额外的清理工作,在验证发生后执行自动修复或在更新发生后更新相关模型。
所有before
钩子在返回false
(特别是布尔值,而不仅仅是“假”值)时将停止操作。因此,举例来说,如果您想在beforeSave
方法出现问题时停止保存,只需return false
,保存就不会发生 - 显然afterSave
也不会被调用。
以下是可用钩子的完整列表:
创建before
/ afterCreate()
afterSave()
before
/之后
更新before
/ afterUpdate()
afterDelete()
before
/之后
before
/ afterValidate()
- 返回 false 时将停止验证,从而使save()
操作也失败,因为验证失败。
例如,您可以使用beforeSave
来哈希用户密码(实际上,使用自动哈希会是一个更好的主意!):
class User extends LaravelArdentArdentArdent { public function beforeSave() {// 如果有新密码,则对其进行哈希 if($this->isDirty('password')) { $this->password = Hash::make($this->password ); } return true;//或者不返回任何内容,因为只有布尔值 false 才会停止操作 } }
beforeSave
和afterSave
可以在运行时包含。只需将模型作为参数传递给save()
(或forceSave()
)方法的闭包即可。
$user->save(array(), array(), array(), function ($model) { // beforeSaveecho 的闭包“保存模型对象...”;return true; }, function ($model) { // afterSaveecho "done!" 的闭包; } );
注意:闭包应该有一个参数,因为它将传递对正在保存的模型的引用。
您是否曾经编写过包含一堆关系的 Eloquent 模型,只是注意到您的类有多么混乱,所有那些与方法名称本身内容几乎相同的单行话?
在 Ardent 中,您可以使用其信息在数组中清晰地定义关系,并且它们的工作方式就像您在方法中定义它们一样。这是一个例子:
class User extends LaravelArdentArdentArdent { public static $relationsData = array('address' => array(self::HAS_ONE, 'Address'),'orders' => array(self::HAS_MANY, 'Order'),'groups' = > 数组(self::BELONGS_TO_MANY, '组', '表' => 'groups_have_users') ); }$user = User::find($id);echo "{$user->address->street}, {$user->address->city} - {$user->address->state}";
数组语法如下:
第一个索引值:关系名称,为hasOne
、 hasMany
、 belongsTo
、 belongsToMany
、 morphTo
、 morphOne
、 morphMany
之一或相关常量之一(例如Ardent::HAS_MANY
或Ardent::MORPH_ONE
)。
第二个索引:类名,具有完整的命名空间。 morphTo
关系是个例外,它不需要额外的参数。
命名参数,遵循为原始 Eloquent 方法定义的参数:
foreignKey
[可选],对hasOne
、 hasMany
、 belongsTo
和belongsToMany
有效
table
、 otherKey
[可选]、 timestamps
[布尔值,可选] 和pivotKeys
[数组,可选],对belongsToMany
有效
name
、 type
和id
,由morphTo
、 morphOne
和morphMany
使用(最后两个需要定义name
)
注意:此功能基于 Yii 1.1 ActiveRecord 上的简单关系。
Ardent 能够自动从表单输入提交中合并您的实体模型类!
让我们看看它的动作。考虑一下这段代码:
$user = 新用户;$user->name = Input::get('name');$user->email = Input::get('email');$user->password = Hash::make(Input ::get('密码'));$user->save();
让我们调用 Ardent 的魔力并重写前面的代码片段:
$user = 新用户;$user->save();
就是这样!我们所做的就是删除那些无聊的东西。
不管你相信与否,上面的代码执行的任务与它的旧代码(尽管相当冗长)基本相同。 Ardent 使用用户提交的表单数据中的属性填充模型对象。不再费力地试图找出您忘记填充的 Eloquent 属性。让 Ardent 处理无聊的事情,而您则可以继续有趣的事情!
它在内部遵循相同的质量分配规则,具体取决于$fillable
/ $guarded
属性。
要启用自动水合功能,只需在模型类中将$autoHydrateEntityFromInput
实例变量设置为true
即可。但是,为了防止填充预先存在的属性,如果您还希望在更新场景中自动水合,则应该使用$forceEntityHydrationFromInput
:
类 User 扩展 LaravelArdentArdentArdent { public $autoHydrateEntityFromInput = true; // 水合新条目的验证 公共$forceEntityHydrationFromInput = true; // 每当调用验证时都会水化}
Ardent 模型可以自动神奇地清除冗余输入数据(例如密码确认、隐藏的 CSRF _token
或自定义 HTTP _method
字段),以便额外的数据永远不会保存到数据库中。 Ardent 将使用确认字段来验证表单输入,然后在将模型实例保存到数据库之前谨慎地丢弃这些属性!
要启用此功能,只需在模型类中将$autoPurgeRedundantAttributes
实例变量设置为true
即可:
类 User 扩展 LaravelArdentArdentArdent { public $autoPurgeRedundantAttributes = true; }
您还可以清除其他字段。属性Ardent::$purgeFilters
是一个闭包数组,您可以向其中添加自定义规则。这些闭包接收属性键作为参数,并且对于应清除的属性应返回false
。像这样:
函数 __construct($attributes = array()) { 父级::__construct($attributes); $this->purgeFilters[] = function($key) {$purge = array('tempData', 'myAttribute');return ! in_array($key, $purge); }; }
假设您的模型类中有一个名为password
的属性,但不想在数据库中存储纯文本版本。务实的做法是存储原始内容的哈希值。不用担心,Ardent 完全有能力为您自动变换任意数量的安全字段!
为此,请将属性名称添加到模型类中的Ardent::$passwordAttributes
静态数组变量中,并将$autoHashPasswordAttributes
实例变量设置为true
:
class User 扩展 LaravelArdentArdentArdent { 公共静态 $passwordAttributes = array('password'); 公共 $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 文档:
'电子邮件' => '唯一:用户,电子邮件,10'
过去,程序员必须手动管理 ID 的传递和规则集的更改以在运行时包含 ID。但热心却并非如此。只需使用unique
设置规则,调用函数updateUniques
,Ardent 将处理剩下的事情。
在您的扩展模型中定义您的规则
公共静态 $rules = array( '电子邮件' => '必需|电子邮件|唯一', '密码' => '必需|之间:4,20|确认', 'password_confirmation' => '之间:4,20', );
在你的控制器中,当你需要更新时,只需调用
$模型->updateUniques();
如果需要,您可以在运行时将规则传递给updateUniques
,否则它将使用模型提供的静态规则。
请注意,在上面的规则示例中,我们没有告诉验证器要使用哪个表甚至哪个字段,如 Laravel 文档中所述(即unique:users,email,10
)。热心足够聪明,能够弄清楚这一点。 (感谢github用户@Sylph)