創(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之前的版本复罐,需要在AppServiceProvider
的boot()
中配置Schema::defaultStringLength(191);
自動創(chuàng)建的資源管理方法相關(guān):
// 為路由設(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);