Laravel手记

创建Laravel项目

$ composer create-project --prefer-dist laravel/laravel blog

安装依赖

$ brew install composer # 安装composer
$ composer global require laravel/installer # 全局安装laravel

项目使用

$ composer create-project --prefer-dist laravel/laravel blog # 创建blog项目
$ php artisan make:controller TestController # 创建test controller

$ composer require sven/artisan-view # 给artisan增加创建view的功能
$ php artisan make:view test.index # 创建test目录下的view

$ php artisan make:controller PostController --resource # 创建post controller并且自动创建get / post / delete等CURD函数

// 可以通过 Route::resource('post', 'PostController'); 来注册所有路由

$ php artisan route:list # 查看当前项目所有路由

$ php artisan make:migration create_site_table --create=sites # 创建迁移文件create_site_table、数据库表sites
$ php artisan migrate # 执行数据库迁移

$ php artisan make:model UserProfile -m # 可以创建用户模型以及数据表结构,免去执行 make:migration了

$ php artisan make:seeder UsersTableSeeder # 创建填充类
$ php artisan db:seed --class=UsersTableSeeder # 执行填充

$ php artisan make:model Post # 创建数据表模型
$ php artisan make:factory PostFactory --model=Post # 为Post创建模型工厂

$ composer require laravel/ui # 安装前端ui
$ php artisan ui vue --auth # 创建用户认证脚手架代码

mysql 5.57之前的版本,需要在AppServiceProviderboot()中配置Schema::defaultStringLength(191);

自动创建的资源管理方法相关:


image.png
// 为路由设置别名
Route::get('/', 'TaskController@home')->name('task');
$url = route('task');
// 内连查询模式
$posts = DB::table('posts')
    ->join('users', 'users.id', '=', 'posts.user_id')
    ->select('posts.*', 'users.name', 'users.email')
    ->get();

// 左连查询模式 返回左边表所有数据 右边没有的表示为空

$posts = DB::table('posts')
    ->leftJoin('users', 'users.id', '=', 'posts.user_id')
    ->select('posts.*', 'users.name', 'users.email')
    ->get();

// 右连接查询模式 返回右边所有数据表,左边没有的显示为空
$posts = DB::table('posts')
    ->rightJoin('users', 'users.id', '=', 'posts.user_id')
    ->select('posts.*', 'users.name', 'users.email')
    ->get();
// 创建一个访问器,在model类里面创建即可
// 函数名的命名方式为驼峰命名
// 这样后续约定成俗的可以用 $user->display_name 这样的方式来方位
// User.php 
public function getDisplayNameAttribute()
{
    return $this->nickname ? $this->nickname : $this->name;
}

// 使用方法
// UserController.php

public function show($id){
    $user = User::find($id);
    $user->display_name; // 按上面访问器规则,如果未设置nickname则输出name
}

// 创建修改器 需要在mode里创建,
// User.php
public function setCardNoAttribute($value)
{
    $value = str_replace(' ', '', $value);  // 将所有空格去掉
    $this->attributes['card_no'] = encrypt($value);
}

// 通过模型创建
// UserController.php
$user = new User($request->all());
return $user->save();

// 通过模型更新
// UserController.php
$user = User::find($id);
$user->fill($request->all())->save();

// 以上通过模型增加 / 修改需要先更新模型里面的字段白名单,只有白名单的数据才会被更新或创建
// User.php
protected $fillable = [
    'name', 'email', 'password','card_no'
];

模型事件类型:

retrieved:获取到模型实例后触发
creating:插入到数据库前触发
created:插入到数据库后触发
updating:更新到数据库前触发
updated:更新到数据库后触发
saving:保存到数据库前触发(插入/更新之前,无论插入还是更新都会触发)
saved:保存到数据库后触发(插入/更新之后,无论插入还是更新都会触发)
deleting:从数据库删除记录前触发
deleted:从数据库删除记录后触发
restoring:恢复软删除记录前触发
restored:恢复软删除记录后触发

// 通过静态方法监听事件
// app/Providers/EventServiceProvider.php
// 日志默认存放在 storage/logs/laravel.log
public function boot(){
    parent::boot();
    User::retrieved(function ($user) {
        Log::info('从模型中获取用户[' . $user->id . ']:' . $user->name);
    });
}

通过订阅者监听模型事件

// 通过订阅者监听模型事件
// 1. 创建事件 
// 2. 修改填充事件构造方法
// 3. 在 app/Listeners目录创建订阅类 UserEventSubscriber.php
// 4. 在EventServiceProvider中注册订阅者

$ php artisan make:event UserDeleting

// app/Events/UserDeleting.php
public $user;
public function __construct(User $user)
{
    $this->user = $user;
}

<?php
namespace App\Listeners;

use App\Events\UserDeleting; // 引入对应的类
use Illuminate\Support\Facades\Log;

class UserEventSubscriber
{
    // 处理用户删除前事件
    public function onUserDeleting($event) {
        Log::info('用户即将删除[' . $event->user->id . ']:' . $event->user->name);
    }

    // 为订阅者注册监听器
    public function subscribe($events)
    {
        $events->listen(
            UserDeleting::class,
            UserEventSubscriber::class . '@onUserDeleting'
        );
    }
}

// app/Providers/EventServiceProvider.php
protected $subscribe = [
    UserEventSubscriber::class
];

通过观察者监听模型事件

// 通过观察者监听模型事件
// 1. 创建初始化观察者,会自动生成各种监听函数,在里面写逻辑即刻
// 2. 编写逻辑 app/Observers/UserObserver.php
// 3. 在EventServiceProvider中的boot方法中注册

$ php artisan make:observer UserObserver --model=User

// app/Observers/UserObserver.php
public function updated(User $user)
{
    Log::info('已经更新用户到数据库[' . $user->id . ']' . $user->name);
}

// app/Providers/EventServiceProvider.php
public function boot()
{
    parent::boot();
    User::observe(UserObserver::class);
}

填充数据表

// 1. 编写填充器类
// 2. 创建模型工厂 
// 3. 编写模型工厂 UserProfilesFactory
// 4. 在填充器里 调用模型工厂 UserProfilesTableSeeder
// 5. 命令行执行调用命令
$ php artisan make:seeder UserProfilesTableSeeder
$ php artisan make:factory UserProfilesFactory --model UserProfile

// 编写模型工厂
return [
    'user_id'=>$faker->numberBetween(1,20),
    'bio'=>$faker->realText(),
    'city'=>$faker->city()
];

// 在填充器里 调用模型工厂
factory(\App\UserProfile::class, 10)->create();

$ php artisan db:seed --class=UserProfilesTableSeeder

模型关联 一对一

// 建立关联关系,比如用户表 与 用户资料表
// 在用户模型里关联用户资料模型,调用的时候是 $user->profile;
public function profile()
{
    return $this->hasOne(UserProfile::class);
}
// 相对关联,比如用户资料表 与 用户表
public function user()
{
    return $this->belongsTo(User::class);
}

模型关联 一对多

// 建立关联关系,比如在用户表关联文章表,一个用户可以发多个文章

public function posts()
{
    return $this->hasMany(Post::class);
}

// 使用方法
$posts = $user->posts;

// 建立相对的关联关系 比如从文章表关联用户表,用于查询某篇文章是谁发的
public function user()
{
    return $this->belongsTo(User::class);
}
// 使用方法
$author = $post->user; // 获取用户信息

public function author() // 功能与上面的 user() 一样
{
    return $this->belongsTo(User::class, 'user_id', 'id', 'author');
}

渴求式加载 直接一次查询出所有信息

$post = Post::with('author')
    ->where('views', '>', 0)
    ->get();

return $post;

多对多建立关系

// 多对多需要一个中间表来维护关系
// 比如 文章表 与 标签表 需要一个 post_tags 的表来维护
// 设置 post_id 与 tag_id不可以重复 可以避免数据浪费
// 因为多对多是平等关系,所以建立相对关联关系也是一样的操作

// 在Post模型中直接指定tags
public function tags()
{
    return $this->belongsToMany(Tag::class, 'post_tags');
}

// 在Tag模型中指定posts
public function posts()
{
    return $this->belongsToMany(Post::class, 'posts');
}

// 使用的时候直接调用即可
$post = Post::find($id)->tags;
$post = Post::with('tags')->find($id);

// 如有多个with需要绑定,可以给with传递数组
$post = Post::with(['author', 'tags'])->find($id);

分页关键代码

public function fetch()
{
    //                      每页显示6条   当前页码左右显示2个
    $posts = Post::paginate(6)->onEachSide(2)->withPath(url('post'));

    $window = UrlWindow::make($posts);

    $pages = array_filter([
        $window['first'],
        is_array($window['slider']) ? '...': null,
        is_array($window['last']) ? '...':null,
        $window['last']
    ]);

    return response()->json([
        'paginator'=>$posts,
        'elements'=>$pages
    ]);
}

vue使用

// 1. 创建vue组建文件,在resources/js/components目录创建WelcomeComponent.vue
// 2. 注册vue组建 resources/js/app.js
// 3. 在页面中调用即可
Vue.component('pagination-component', require('./components/PaginationComponent.vue').default);
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,539评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,911评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,337评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,723评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,795评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,762评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,742评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,508评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,954评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,247评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,404评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,104评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,736评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,352评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,557评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,371评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,292评论 2 352