现在是2017年2月5日,从开始接触Laravel也有小一年来了,这篇文章将记录我使用Laravel的一些新得。新的想法也将随时更新到这篇文章中。
1.目录别名
1.1说明
在ShenCom他们有一点做的很好,就是把框架外的扩展全部放在了一个独立的目录里面,没有去破坏Laravel框架本身的结构,让框架保持了原来的特性,又增加了新的功能。
1.2用法
1.2.1添加主服务文件
在 app\Providers\AppServiceProvider的boot方法中添加
App::register("\YaZhou\YaZhouServiceProvider");
1.2.2起别名
在compser.json里面增加一个autoload选项。
执行命令composer dump-autpload
2.模型(Model)的定义
2.1简单示例
namespace Yz\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Test extends Model{
use SoftDeletes;
protected $primaryKey = "id";
protected $table = "test";
protected $guarded = ["id"];
public $timestamps = false;
}
2.2代码说明
protected $table
指定当前模型对应的数据表名。
protected $primaryKey
指定当前数据表的主键,默认id。
public $timestamps
默认情况下,Eloquent期望created_at和updated_at已经存在于数据表中,如果你不想要这些Laravel自动管理的列,在模型类中设置$timestamps属性为false。
protected $guarded/$fillale
在使用create方法保存一个新的模型时,所有的Eloquent模型都通过批量赋值(Mass Assignment)进行保护,需要指定模型的fillable或guarded属性。在fillable里面的都是可以被赋值的(白名单),在guarded里面的都是不可以被赋值的(黑名单),fillable和guarded二选一。
use SoftDeletes
软删除,要求数据表中以一个字段“deleted_at”。被软删除的记录并没有被真正的删除,只是在“deleted_at”字段记录了操作时间。
Model::withTrashed()->...
,同时获取被软删除的记录。
Model::onlyTrashed()->...
,只获取被软删除的记录。
$record->restore();
,恢复被软删除的记录。
$record->forceDelete()
,强制删除。
$record-> history() -> forceDelete()
,强制删除所有关模型。
2.3扩展
查询作用域
作用域允许你定义一个查询条件的通用集合,这样就可以在应用中方便地复用。详情参见,Laravel5.1中文文档。
3.模型关系
3.1一对一关系
3.1.1关系的定义
namespace Yz\Test\Models;
use Illuminate\Database\Eloquent\Model;
class User extends Model{
// 获取关联到用户的手机
public function phone(){
return $this->hasOne("Yz\Test\Models\Phone");
// 这种写法默认Phone模型中有一个user_id外键,默认与当前模型的id关联
// return $this->hasOne("Yz\Test\Models\Phone", "user_id");
// 指定Phone模型中的外键,默认与当前模型的id关联
// return $this->hasOne("Yz\Test\Models\Phone", "user_id", "id");
// 指定phone模型的外键,同时指定当前模型的关联键,推荐使用
}
}
3.1.2定义关系的相对关联
namespace Yz\Test\Models;
use Illuminate\Database\Eloquent\Model;
class Phone extends Model{
public function user(){
// 找到电话所属的用户
return $this->belongsTo("Yz\Test\Models\User");
// 默认通过当前表的user_id去匹配user表的id
// return $this->belongsTo("Yz\Test\Models\User", "user_id");
// 指定当前表的关联字段,去与主表的id字段进行匹配
// return $this->belongsTo("Yz\Test\Models\User", "user_id", "id");
// 指定当前表的user_id与User表的id进行匹配,推荐使用
}
}
3.1.3一对一关系的使用
$phone = User::find(1)->phone;
3.2 一对多关系
3.2.1关系的定义
namespace Yz\Test\Models;
use Illuminate\Database\Eloquent\Model;
class Post extends Model{
/*博客数据*/
public function comments(){
// 获取博客的评论
return $this->hasMany("Yz\Test\Models\Comment");
// $this->hasMany("Yz\Test\Models\Comment", "post_id");
// $this->hasMany("Yz\Test\Models\Comment", "post_id", "id");
}
}
3.2.2定义关系的相对关联
namespace Yz\Test\Models;
use Illuminate\Database\Eloquent\Model;
class Comment extends Model{
/*博客的评论*/
public function post(){
return $this->belongsTo("Yz\Test\Models\Post");
// return $this->belongsTo("Yz\Test\Models\Post", "post_id");
// return $this->belongsTo("Yz\Test\Models\Post", "post_id", "id");
}
}
3.2.3一对多关系的使用
$comments = App\Post::find(1)->comments;
$comments = App\Post::find(1)->comments()->where('title', 'foo')->first();
$comment = App\Comment::find(1);
echo $comment->post->title;
3.3多对多关系
实现多对多关系需要一个中间表。比如,一个用户(user)拥有多种角色(role),那么我们就需要一个中间表(user_role)。
3.3.1关系的定义
public function roles(){
return $this->belongsToMany("Yz\Test\Model\Role");
// 省略写法,要求中间表的名字为role_user,且中间表包含role_id和user_id两个字段
// return $this->belongsToMany("Yz\Test\Models\Role", "user_role");
// 半完整写法
// return $this->belongsToMany("Yz\Test\Models\Role", "user_role", "user_id", "role_id");
// 完整写法
}
3.3.2定义关系的相对关联
namespace Yz\Test\Models;
use Illuminate\Database\Eloquent\Model;
class Role extends Model
{
// 用户角色
public function users()
{
// 找到属于当前角色的用户
return $this->belongsToMany("Yz\Test\Models\User");
// return $this->belongsToMany("Yz\Test\Models\User", "user_role");
// return $this->belongsToMany("Yz\Test\Models\User", "user_role", "role_id", "user_id");
}
}
3.3.3多对多关系的使用
$user = App\User::find(1);
foreach ($user->roles as $role) {
//
}
$roles = App\User::find(1)->roles()->orderBy('name')->get();
3.4插入关联模型
3.4.1插入一个关联模型
$comment = new App\Comment(['message' => 'A new comment.']);
$post = App\Post::find(1);
$comment = $post->comments()->save($comment);
3.4.2插入多个关联模型
$post = App\Post::find(1);
$post->comments()->saveMany([
new App\Comment(['message' => 'A new comment.']),
new App\Comment(['message' => 'Another comment.']),
]);
除了save和saveMany方法外,还可以使用create方法,该方法接收属性数组、创建模型、然后插入数据库。save和create的不同之处在于save接收整个Eloquent模型实例而create接收原生PHP数组。
$post = App\Post::find(1);
$comment = $post->comments()->create([
'message' => 'A new comment.',
]);
3.4.3更新关联模型
更新belongsTo关联的时候,可以使用associate方法,该方法会在子模型设置外键。
$account = App\Account::find(10);
$user->account()->associate($account);
$user->save();
3.4.4移除关联模型
移除belongsTo关联的时候,可以使用dissociate方法。该方法在子模型上取消外键和关联。
$user->account()->dissociate();
$user->save();
3.4.5多对多关系的附加
$user = App\User::find(1);
$user->roles()->attach($roleId);
附加关联关系到模型,还可以以数组形式传递额外被插入数据到中间表:
$user->roles()->attach($roleId, ['expires' => $expires])
3.4.6多对多关系的移除
// 从指定用户中移除角色...
$user->roles()->detach($roleId);
// 从指定用户移除所有角色...
$user->roles()->detach();
为了方便,attach和detach还接收数组形式的ID作为输入。
$user = App\User::find(1);
$user->roles()->detach([1, 2, 3]);
$user->roles()->attach([1 => ['expires' => $expires], 2, 3]);
3.4.7触发父级时间戳
当一个模型属于另外一个时,例如Comment属于Post,子模型更新时父模型的时间戳也被更新将很有用,例如,当Comment模型被更新时,你可能想要”触发“创建其所属模型Post的updated_at时间戳。Eloquent使得这项操作变得简单,只需要添加包含关联关系名称的touches属性到子模型中即可。