Laravel手記

創(chuàng)建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 # 創(chuàng)建blog項目
$ php artisan make:controller TestController # 創(chuàng)建test controller

$ composer require sven/artisan-view # 給artisan增加創(chuàng)建view的功能
$ php artisan make:view test.index # 創(chuàng)建test目錄下的view

$ php artisan make:controller PostController --resource # 創(chuàng)建post controller并且自動創(chuàng)建get / post / delete等CURD函數(shù)

// 可以通過 Route::resource('post', 'PostController'); 來注冊所有路由

$ php artisan route:list # 查看當前項目所有路由

$ php artisan make:migration create_site_table --create=sites # 創(chuàng)建遷移文件create_site_table露氮、數(shù)據(jù)庫表sites
$ php artisan migrate # 執(zhí)行數(shù)據(jù)庫遷移

$ php artisan make:model UserProfile -m # 可以創(chuàng)建用戶模型以及數(shù)據(jù)表結(jié)構(gòu)缕贡,免去執(zhí)行 make:migration了

$ php artisan make:seeder UsersTableSeeder # 創(chuàng)建填充類
$ php artisan db:seed --class=UsersTableSeeder # 執(zhí)行填充

$ php artisan make:model Post # 創(chuàng)建數(shù)據(jù)表模型
$ php artisan make:factory PostFactory --model=Post # 為Post創(chuàng)建模型工廠

$ composer require laravel/ui # 安裝前端ui
$ php artisan ui vue --auth # 創(chuàng)建用戶認證腳手架代碼

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

自動創(chuàng)建的資源管理方法相關(guān):


image.png
// 為路由設(shè)置別名
Route::get('/', 'TaskController@home')->name('task');
$url = route('task');
// 內(nèi)連查詢模式
$posts = DB::table('posts')
    ->join('users', 'users.id', '=', 'posts.user_id')
    ->select('posts.*', 'users.name', 'users.email')
    ->get();

// 左連查詢模式 返回左邊表所有數(shù)據(jù) 右邊沒有的表示為空

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

// 右連接查詢模式 返回右邊所有數(shù)據(jù)表悍手,左邊沒有的顯示為空
$posts = DB::table('posts')
    ->rightJoin('users', 'users.id', '=', 'posts.user_id')
    ->select('posts.*', 'users.name', 'users.email')
    ->get();
// 創(chuàng)建一個訪問器蒂破,在model類里面創(chuàng)建即可
// 函數(shù)名的命名方式為駝峰命名
// 這樣后續(xù)約定成俗的可以用 $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; // 按上面訪問器規(guī)則扒接,如果未設(shè)置nickname則輸出name
}

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

// 通過模型創(chuàng)建
// UserController.php
$user = new User($request->all());
return $user->save();

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

// 以上通過模型增加 / 修改需要先更新模型里面的字段白名單,只有白名單的數(shù)據(jù)才會被更新或創(chuàng)建
// User.php
protected $fillable = [
    'name', 'email', 'password','card_no'
];

模型事件類型:

retrieved:獲取到模型實例后觸發(fā)
creating:插入到數(shù)據(jù)庫前觸發(fā)
created:插入到數(shù)據(jù)庫后觸發(fā)
updating:更新到數(shù)據(jù)庫前觸發(fā)
updated:更新到數(shù)據(jù)庫后觸發(fā)
saving:保存到數(shù)據(jù)庫前觸發(fā)(插入/更新之前乞娄,無論插入還是更新都會觸發(fā))
saved:保存到數(shù)據(jù)庫后觸發(fā)(插入/更新之后瞬逊,無論插入還是更新都會觸發(fā))
deleting:從數(shù)據(jù)庫刪除記錄前觸發(fā)
deleted:從數(shù)據(jù)庫刪除記錄后觸發(fā)
restoring:恢復(fù)軟刪除記錄前觸發(fā)
restored:恢復(fù)軟刪除記錄后觸發(fā)

// 通過靜態(tài)方法監(jiān)聽事件
// app/Providers/EventServiceProvider.php
// 日志默認存放在 storage/logs/laravel.log
public function boot(){
    parent::boot();
    User::retrieved(function ($user) {
        Log::info('從模型中獲取用戶[' . $user->id . ']:' . $user->name);
    });
}

通過訂閱者監(jiān)聽模型事件

// 通過訂閱者監(jiān)聽模型事件
// 1. 創(chuàng)建事件 
// 2. 修改填充事件構(gòu)造方法
// 3. 在 app/Listeners目錄創(chuàng)建訂閱類 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; // 引入對應(yīng)的類
use Illuminate\Support\Facades\Log;

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

    // 為訂閱者注冊監(jiān)聽器
    public function subscribe($events)
    {
        $events->listen(
            UserDeleting::class,
            UserEventSubscriber::class . '@onUserDeleting'
        );
    }
}

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

通過觀察者監(jiān)聽模型事件

// 通過觀察者監(jiān)聽模型事件
// 1. 創(chuàng)建初始化觀察者,會自動生成各種監(jiān)聽函數(shù)仪或,在里面寫邏輯即刻
// 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('已經(jīng)更新用戶到數(shù)據(jù)庫[' . $user->id . ']' . $user->name);
}

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

填充數(shù)據(jù)表

// 1. 編寫填充器類
// 2. 創(chuàng)建模型工廠 
// 3. 編寫模型工廠 UserProfilesFactory
// 4. 在填充器里 調(diào)用模型工廠 UserProfilesTableSeeder
// 5. 命令行執(zhí)行調(diào)用命令
$ 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()
];

// 在填充器里 調(diào)用模型工廠
factory(\App\UserProfile::class, 10)->create();

$ php artisan db:seed --class=UserProfilesTableSeeder

模型關(guān)聯(lián) 一對一

// 建立關(guān)聯(lián)關(guān)系确镊,比如用戶表 與 用戶資料表
// 在用戶模型里關(guān)聯(lián)用戶資料模型,調(diào)用的時候是 $user->profile;
public function profile()
{
    return $this->hasOne(UserProfile::class);
}
// 相對關(guān)聯(lián)范删,比如用戶資料表 與 用戶表
public function user()
{
    return $this->belongsTo(User::class);
}

模型關(guān)聯(lián) 一對多

// 建立關(guān)聯(lián)關(guān)系蕾域,比如在用戶表關(guān)聯(lián)文章表,一個用戶可以發(fā)多個文章

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

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

// 建立相對的關(guān)聯(lián)關(guān)系 比如從文章表關(guān)聯(lián)用戶表瓶逃,用于查詢某篇文章是誰發(fā)的
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;

多對多建立關(guān)系

// 多對多需要一個中間表來維護關(guān)系
// 比如 文章表 與 標簽表 需要一個 post_tags 的表來維護
// 設(shè)置 post_id 與 tag_id不可以重復(fù) 可以避免數(shù)據(jù)浪費
// 因為多對多是平等關(guān)系束铭,所以建立相對關(guān)聯(lián)關(guān)系也是一樣的操作

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

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

// 使用的時候直接調(diào)用即可
$post = Post::find($id)->tags;
$post = Post::with('tags')->find($id);

// 如有多個with需要綁定,可以給with傳遞數(shù)組
$post = Post::with(['author', 'tags'])->find($id);

分頁關(guān)鍵代碼

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. 創(chuàng)建vue組建文件厢绝,在resources/js/components目錄創(chuàng)建WelcomeComponent.vue
// 2. 注冊vue組建 resources/js/app.js
// 3. 在頁面中調(diào)用即可
Vue.component('pagination-component', require('./components/PaginationComponent.vue').default);
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市带猴,隨后出現(xiàn)的幾起案子昔汉,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,194評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件靶病,死亡現(xiàn)場離奇詭異会通,居然都是意外死亡,警方通過查閱死者的電腦和手機娄周,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評論 2 385
  • 文/潘曉璐 我一進店門涕侈,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人煤辨,你說我怎么就攤上這事裳涛。” “怎么了众辨?”我有些...
    開封第一講書人閱讀 156,780評論 0 346
  • 文/不壞的土叔 我叫張陵端三,是天一觀的道長。 經(jīng)常有香客問我鹃彻,道長郊闯,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,388評論 1 283
  • 正文 為了忘掉前任蛛株,我火速辦了婚禮团赁,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘谨履。我一直安慰自己然痊,他們只是感情好,可當我...
    茶點故事閱讀 65,430評論 5 384
  • 文/花漫 我一把揭開白布屉符。 她就那樣靜靜地躺著剧浸,像睡著了一般。 火紅的嫁衣襯著肌膚如雪矗钟。 梳的紋絲不亂的頭發(fā)上唆香,一...
    開封第一講書人閱讀 49,764評論 1 290
  • 那天,我揣著相機與錄音吨艇,去河邊找鬼躬它。 笑死,一個胖子當著我的面吹牛东涡,可吹牛的內(nèi)容都是我干的冯吓。 我是一名探鬼主播,決...
    沈念sama閱讀 38,907評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼疮跑,長吁一口氣:“原來是場噩夢啊……” “哼组贺!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起祖娘,我...
    開封第一講書人閱讀 37,679評論 0 266
  • 序言:老撾萬榮一對情侶失蹤失尖,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體掀潮,經(jīng)...
    沈念sama閱讀 44,122評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡菇夸,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,459評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了仪吧。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片庄新。...
    茶點故事閱讀 38,605評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖薯鼠,靈堂內(nèi)的尸體忽然破棺而出择诈,到底是詐尸還是另有隱情,我是刑警寧澤人断,帶...
    沈念sama閱讀 34,270評論 4 329
  • 正文 年R本政府宣布吭从,位于F島的核電站,受9級特大地震影響恶迈,放射性物質(zhì)發(fā)生泄漏涩金。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,867評論 3 312
  • 文/蒙蒙 一暇仲、第九天 我趴在偏房一處隱蔽的房頂上張望步做。 院中可真熱鬧,春花似錦奈附、人聲如沸全度。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽将鸵。三九已至,卻和暖如春佑颇,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背挑胸。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評論 1 265
  • 我被黑心中介騙來泰國打工痒筒, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人茬贵。 一個月前我還...
    沈念sama閱讀 46,297評論 2 360
  • 正文 我出身青樓戳粒,卻偏偏與公主長得像评雌,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子直焙,可洞房花燭夜當晚...
    茶點故事閱讀 43,472評論 2 348