30分鐘用 Laravel 實(shí)現(xiàn)一個(gè)博客

介紹

  • Laravel 是一款 MVC架構(gòu)燕刻、 目前最流行的 PHP框架皇忿。
  • Laravel的優(yōu)點(diǎn)在于: 豐富的composer類庫支持, 優(yōu)雅的代碼鼎天, 未來的主流框架(目前市場占有率最高的框架)
  • Laravel的缺點(diǎn)在于: 過于優(yōu)雅(我們只需要編寫極少的代碼即可實(shí)現(xiàn)功能颜凯,意味著底層極其復(fù)雜的封裝)導(dǎo)致程序的執(zhí)行效率略低谋币, 和thinkphp等國內(nèi)主流框架相比,上手難度略高(因?yàn)樗鼮槲覀兗闪撕芏嗥渌墓δ苤⒏牛踔聊氵€需要學(xué)習(xí)nodeJS相關(guān)的知識(shí))蕾额。
  • 本項(xiàng)目,是完全使用 Laravel框架 內(nèi)的所提供的最基礎(chǔ)彼城,但是又是最有用(能顯著提升我們開發(fā)效率)的工具而開發(fā)出來的诅蝶。在學(xué)習(xí)過程中,你只需要操作一次數(shù)據(jù)庫募壕,不需要自己構(gòu)建html視圖模板(當(dāng)然還是要寫一些html和js代碼的)调炬,不需要考慮外部的css、js舱馅。本教程的目的完全為向各位 phper 以及對 laravel 有興趣的小伙伴推薦這款我相信是未來主流的php框架缰泡。

準(zhǔn)備工作

  • 確保你了解 php面向?qū)ο缶幊?的基礎(chǔ)知識(shí), 會(huì)html和簡單的js代嗤, 在css方面: 我們使用laravel內(nèi)置的 bootstrap4棘钞, 最后,一定要會(huì)使用 composer干毅。
  • 唯一一次操作數(shù)據(jù)庫: 創(chuàng)建用戶宜猜、數(shù)據(jù)庫,授權(quán)

如果你愿意用root用戶溶锭,你甚至只需要 create 一個(gè) database 即可。 (不過不推薦符隙,我的習(xí)慣是一個(gè)項(xiàng)目 對應(yīng) 一個(gè)用戶 + 一個(gè)數(shù)據(jù)庫趴捅,root則只用來管理他們)

# 創(chuàng)建用戶 blog, 密碼自定義
CREATE USER 'blog'@'%' IDENTIFIED BY '密碼';
# 創(chuàng)建數(shù)據(jù)庫 blog, 設(shè)置默認(rèn)編碼為utf8
CREATE DATABASE `blog` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
# 授權(quán) 授予 blog庫下所有表的 所有權(quán)限 給 用戶blog
GRANT ALL on blog.* to 'blog'@'%';
  • 使用 composer 創(chuàng)建一個(gè) laravel 項(xiàng)目 取名叫blog
# 進(jìn)入你本地服務(wù)器用于存放網(wǎng)站文檔的目錄垫毙,輸入命令
composer create-project --prefer-dist laravel/laravel blog
  • 你還需要配置一個(gè)虛擬主機(jī)以提升開發(fā)效率(直接訪問url,不需要 “l(fā)ocalhost/項(xiàng)目/public” 訪問 )拱绑,你可以選擇手動(dòng)配置综芥,或者選擇集成開發(fā)環(huán)境創(chuàng)建項(xiàng)目(推薦:mac=>mamp 、 windows=>laragon猎拨。linux=>寶塔面板)膀藐。

下文中,“/” 即表示 laravel 框架的根目錄

  • 配置 /.env 文件
# 數(shù)據(jù)庫配置
DB_CONNECTION=mysql #類型
DB_HOST=127.0.0.1 #ip
DB_PORT=3306 #端口
DB_DATABASE=數(shù)據(jù)庫名
DB_USERNAME=用戶名
DB_PASSWORD=密碼
  • 下載中文包 composer require caouecs/laravel-lang 然后將 /vendor/caouecs/src/zh-CN/ 放入 /resources/lang/ 下
  • 配置一下 /config/app.php
# 時(shí)區(qū)
'timezone' => 'Asia/Shanghai',
# 語言
'locale' => 'zh-CN',

準(zhǔn)備工作總結(jié)

  • 1红省、創(chuàng)建用戶额各、數(shù)據(jù)庫,然后授權(quán)吧恃。
  • 2虾啦、使用 composer 創(chuàng)建項(xiàng)目。
  • 3痕寓、配置 laravel 的環(huán)境 ./env 傲醉。 然后使用 composer 安裝了漢化包,并且在 /config/app.php 中設(shè)置時(shí)區(qū)并且讓中文包生效呻率。

第一階段: Migration硬毕、Factory、Seeder

你可能沒有見過上面3個(gè)名詞礼仗,不過和他們有關(guān)的文件都存放在 /database/ 下: 通過這個(gè)文件夾的名稱吐咳,你大概已經(jīng)猜到:這三個(gè)文件都是用來操作數(shù)據(jù)庫的。


  • 上文中藐守,我們只是創(chuàng)建了數(shù)據(jù)庫挪丢,并沒有創(chuàng)建數(shù)據(jù)表,現(xiàn)在來確定一下我們的數(shù)據(jù)表

    • 一個(gè)用戶表 users
    • 一個(gè)博客表 blogs
    • 一個(gè)評(píng)論表 comments

    項(xiàng)目是一個(gè)個(gè)人博客卢厂,因此只有博主可以發(fā)布乾蓬、刪除、修改博客慎恒。其他用戶則可以查看博客和發(fā)布評(píng)論任内。

  • 使用 Migration 創(chuàng)建這3張數(shù)據(jù)表

    • 打開命令行,創(chuàng)建 migrations
      php artisan make:migration create_blogs --create=blogs 博客表融柬,
      php artisan make:migration create_comments --create=comments 評(píng)論表

    php aritsan 是laravel內(nèi)置的命令 你可以直接在控制臺(tái)輸入它死嗦,則會(huì)在控制臺(tái)提示你接下來你能輸入的命令。
    上文我們就使用 make:migration 幫我們創(chuàng)建了遷移文件粒氧, --create 是參數(shù)越除,即告訴這條命令,幫我們創(chuàng)建一個(gè)用于創(chuàng)建數(shù)據(jù)表的遷移文件

  • 為什么不創(chuàng)建用戶表呢? 打開 /database/migrations/ 你會(huì)發(fā)現(xiàn)有一個(gè)2014年就創(chuàng)建好的 針對 users 和 password_resets 表摘盆。這是框架自帶的翼雀。

  • 編輯這兩個(gè)遷移文件

    • create_blogs
    // 首先類定義中,有兩個(gè)方法孩擂,up()可以理解為正向操作:創(chuàng)建表狼渊,而 down()可以理解為回滾操作:刪除表。
    // up()
    Schema::create('blogs', function (Blueprint $table) {
        $table->increments('id');
        $table->string('title');
        $table->text('content');
        $table->timestamps();
    });
    
    // down() 已經(jīng)自動(dòng)幫我們寫好了类垦。
    
    • create_comments
    // up()
    Schema::create('comments', function (Blueprint $table) {
            $table->increments('id');
            $table->string('content');
            $table->integer('blog_id'); //這條評(píng)論是針對哪一篇博客的狈邑?
            $table->integer('user_id'); //這條評(píng)論是哪一位用戶發(fā)送的?
            $table->timestamps();
        });
    
  • 執(zhí)行遷移: 1蚤认、確保你的 /.env 配置正確 2米苹、確保你的數(shù)據(jù)庫可以正常使用 3、確保數(shù)據(jù)庫中沒有數(shù)據(jù)表或者沒有和users blogs comments重名的數(shù)據(jù)表 php artisan migrate

  • 打開數(shù)據(jù)庫(你可以任選一款數(shù)據(jù)庫管理工具烙懦,或者直接使用mysql的命令行)驱入,打開數(shù)據(jù)庫 blog ,你會(huì)發(fā)現(xiàn)有以下表

    • blogs => 我們創(chuàng)建的博客表
    • comments => 我們創(chuàng)建的評(píng)論表
    • migrations => 系統(tǒng)創(chuàng)建的遷移記錄表
    • password_resets => 框架自帶遷移文件生成的重置密碼用表
    • users => 框架自帶的用戶表
  • 主要解釋一下 migrations 表:

    • 這是一個(gè)記錄你的遷移文件名稱和批次的表氯析。它的主要作用是通過記錄批次亏较,方便你對數(shù)據(jù)庫進(jìn)行版本控制:打開 migrations表,你會(huì)發(fā)現(xiàn)掩缓,當(dāng)前記錄了4張表的遷移文件名雪情,而他們的batch都是1,你可以理解為當(dāng)前數(shù)據(jù)庫是第一批你辣,版本1巡通。
    • 如果你執(zhí)行 php artisan migrate:rollback 即回滾數(shù)據(jù)庫,將會(huì)執(zhí)行批次batch最大的記錄的那些遷移文件的 down() 方法舍哄。
  • migration 的作用:1宴凉、幫我們省略了去寫sql語句的麻煩,2表悬、讓我們對數(shù)據(jù)庫可以進(jìn)行有效的版本控制弥锄。


  • 使用模型工廠 Factory 來插入虛構(gòu)的數(shù)據(jù)

在日常的開發(fā)中,我們需要很多模擬的數(shù)據(jù)進(jìn)行測試蟆沫,模型工廠的作用就是幫我們快速的籽暇,隨機(jī)的生成這些數(shù)據(jù)。

  • 創(chuàng)建模型工廠 php artisan make:factory BlogFactory --model=Blog 饭庞, 關(guān)于評(píng)論表的模型工廠請自己寫戒悠。
  • 注意此時(shí)我們其實(shí)沒有模型 Blog 和模型 Comment,我們只是創(chuàng)建了數(shù)據(jù)表而已舟山。因此我們再創(chuàng)建兩個(gè)模型绸狐。
    php artisan make:model Blog卤恳, 關(guān)于評(píng)論表的模型請自己寫。

細(xì)心的你可能發(fā)現(xiàn)了寒矿,我們的數(shù)據(jù)表和模型的名字是有區(qū)別的:數(shù)據(jù)表為“小寫復(fù)數(shù)形式”纬黎,而模型名為“大寫單數(shù)形式”。 創(chuàng)建的模型都存在于 /app/ 下劫窒。

  • 編輯模型工廠 /database/factories
    • BlogFactory
    // 使用 Faker 類為我們提供的生成隨機(jī)偽造數(shù)據(jù)的方法生成數(shù)據(jù) 
     return [
        'title' => $faker->name,
        'content' => $faker->text,
    ];
    
    • CommentFactory
    return [
        'content' => $faker->text,
        'blog_id' => 1,
        'user_id' => 1, 
    ];
    
  • 使用 tinker 模式調(diào)試代碼
    • 進(jìn)入 “修補(bǔ)匠模式” php artisan tinker , 當(dāng)命令提示符變?yōu)?">>>" 時(shí)拆座,你就處于tinker模式下了主巍,此時(shí)你可以輸入php代碼,或者調(diào)用laravel提供的全局函數(shù)挪凑,甚至引用一個(gè)類孕索,調(diào)用它的靜態(tài)方法或者實(shí)例化它。
    • 在 tinker 模式下使用全局函數(shù) factory() 生成模擬的數(shù)據(jù) factory(App\Blog::class)->make() 此時(shí)屏幕上會(huì)顯示躏碳,它給你模擬出來的一個(gè)虛擬數(shù)據(jù)數(shù)組搞旭。
    • 使用 create() 一次性向數(shù)據(jù)表中插入100條模擬的數(shù)據(jù) factory(App\Blog::class, 100)->create() 打開數(shù)據(jù)庫,您會(huì)發(fā)現(xiàn)100條標(biāo)題和內(nèi)容都無關(guān)緊要菇绵,但是對我們快速開發(fā)特別有用的測試數(shù)據(jù)已經(jīng)存放在數(shù)據(jù)庫中了肄渗。

  • 使用 Seeder 一次性完成多個(gè)數(shù)據(jù)庫的批量虛擬數(shù)據(jù)插入
  • 創(chuàng)建 Seeder (如果你處于 tinker, 【ctrl】+【c】 先退出) php artisan make:seeder UserTableSeeder ,針對博客表和評(píng)論表的Seeder創(chuàng)建命令自己寫咬最。
  • 打開 /database/seeds/ 我們創(chuàng)建的Seeder都在這里了翎嫡,不過多了一個(gè) DatabaseSeeder.php,我們等下再來了解它永乌,先編輯其他Seeder惑申,以 UserTableSeeder.php 為例
...
use App\User; // 在 class 關(guān)鍵字前面,引用一下 User 模型

class ...
public function run() 
{
    factory(App\User::class, 50)->create(); //向users表中插入50條模擬數(shù)據(jù)
    $user = User::find(1); //插入完后翅雏,找到 id 為 1 的用戶
    $user->name = "najiuyuanzou"; //設(shè)置 用戶名
    $user->email = "najiuyuanzou@test.com"; //設(shè)置 郵箱
    $user->password = bcrypt('liuhaoyu'); //設(shè)置 密碼
    $user->save(); //保存
}

在這里我們明確1號(hào)用戶為真實(shí)的可用的管理員用戶圈驼!所以我們設(shè)置一下它的 用戶名 郵箱 以及密碼

  • 其余的Seeder我們可以只插入模擬的數(shù)據(jù)即可。

  • 現(xiàn)在回過頭來望几,編輯 DatabaseSeeder

public function run()
{
    // $this->call(UsersTableSeeder::class); // 這里給我們舉例了如何引用其他Seeder
    $this->call(UserTableSeeder::class);
    $this->call(BlogTableSeeder::class);
    $this->call(CommentTableSeeder::class); // 這里有先后關(guān)系需要注意一下: 評(píng)論n : 1文章/用戶绩脆,所以應(yīng)該把它寫在最后
}

  • 使用命令,刷新整個(gè)數(shù)據(jù)庫并且執(zhí)行模擬數(shù)據(jù)插入 php artisan migrate:refresh --seed => 查看數(shù)據(jù)庫橄妆,發(fā)現(xiàn)數(shù)據(jù)庫重置了衙伶,并且 users blogs comments 每張表都有很多虛擬的數(shù)據(jù)。

第一階段總結(jié)

  • 學(xué)習(xí)使用 migrations 的創(chuàng)建害碾、編輯矢劲、執(zhí)行以及回滾: 實(shí)現(xiàn)對數(shù)據(jù)表的結(jié)構(gòu)更改以及數(shù)據(jù)庫版本管理(說白了就是個(gè)帶日志的數(shù)據(jù)表結(jié)構(gòu)管理工具)
  • 學(xué)習(xí)使用 factories 的創(chuàng)建、使用 tinker 調(diào)試慌随、使用 factory() 全局函數(shù)制造和插入數(shù)據(jù)芬沉。
  • 學(xué)習(xí)使用 seeds 的創(chuàng)建(Seeder)躺同、編輯其他Seeder(在 run() 中調(diào)用 factory() )、編輯DatabaseSeed(在 run() 中調(diào)用 其他 Seeder)丸逸。
  • 最后通過它們3個(gè)的配合蹋艺,使用命令刷新了整個(gè)數(shù)據(jù)庫并且分別向3張表插入了很多模擬的數(shù)據(jù),便于我們開發(fā)黄刚。

也許你到這里會(huì)覺得這還不如你寫sql語句捎谨。但是請相信我,等你熟練掌握使用這些東西之后憔维,你的開發(fā)速度會(huì)非程尉龋快!(畢竟你不需要再 "INSERT INTO table values ()" 復(fù)制粘貼修改100遍了)

第二階段: Auth的使用

  • 輸入神奇的命令业扒,看看發(fā)生了什么 php artisan make:auth
  • 打開瀏覽器輸入你配置的虛擬主機(jī)地址检吆,你會(huì)看到一個(gè)Laravel框架的歡迎頁面,這不是重點(diǎn)程储,點(diǎn)擊右上角的 register 蹭沛,你可以注冊賬號(hào),點(diǎn)擊 login 你可以登陸...
  • 本階段結(jié)束章鲤。

第二階段繼續(xù): Auth

  • 好吧你可能很懵逼摊灭,但這就是Laravel的厲害之處,那個(gè)2014年就建好的migration遷移文件可不是個(gè)擺設(shè)败徊。它就是通過操作users表來實(shí)現(xiàn)注冊登陸等等的斟或。

  • php artisan make:auth 到底干了哪些事情呢?

    • 它給你創(chuàng)造了一組控制器集嵌,位于 /app/Http/Controllers/Auth
    • 它在 /routes/web.php 中給你定義了2條路由
    Auth::routes(); //這是用戶操作相關(guān)的路由
    
    Route::get('/home', 'HomeController@index')->name('home'); //這是主頁的路由
    
    • 它給你創(chuàng)造了一組視圖 /resources/views/auth/ 下是用戶操作相關(guān)的路由萝挤, home.blade.php是主頁, layouts/下是布局模板根欧。
  • 我們改良一下它自動(dòng)為我們生成的東西

    • 路由方面 (routes/web.php) 我們將根路由也指向視圖 home.blade.php 怜珍,這是最后的有效代碼:
    // Route::action('uri', 'Controller@function');
    Route::get('/', 'HomeController@index');
    
    Auth::routes();
    
    Route::get('/home', 'HomeController@index')->name('home');
    
    • 控制器方面 app/Http/Controllers/ 我們修改一下 HomeController.php
    /**
     * 這里這個(gè)構(gòu)造函數(shù)調(diào)用了 中間件auth 對我們進(jìn)行權(quán)限認(rèn)證
     * 即要求我們必須登陸才可以訪問該控制器的其他方法
     * 有兩種解決方法,一直是在 $this->middleware('auth')->except('你要排除權(quán)限認(rèn)證的方法')凤粗,比如 ...->except('index')
     * 另一種是直接干掉這個(gè)函數(shù)(我們確定這個(gè)控制器就只是來展示首頁的酥泛,那么就干掉它吧)
     */
    // public function __construct()
    // {
    //     $this->middleware('auth');
    // }
    
    • 視圖方面:HomeController@index (這里我指的是 Home控制器的 index() 方法)調(diào)用了 return view('視圖名稱') 來抓取視圖顯示在頁面上,現(xiàn)在打開瀏覽器訪問主頁嫌拣,你就可以看得到 home.blade.php 中的內(nèi)容了柔袁,我們看看 /resources/views/home.blade.php 的內(nèi)容: 重點(diǎn): @extens @section
    {{--  內(nèi)容不重要我們等下要改,先來看下 @符號(hào) 的作用  --}}
    
    {{--  @extends繼承其他模板  --}}
    @extends('layouts.app') {{--  這里的layouts.app => /resources/views/layouts/app.blade.php  --}}
    
    {{--  @section 填充在布局模板上用 @yield 標(biāo)注的占位符  --}}
    @section('content') {{--  你可以在 /resources/views/layouts/app.blade.php 看到 @ yield('content')標(biāo)注的占位符 --}}
        ... 這里面是html內(nèi)容
    @endsection
    

    Auth為我們生成的整個(gè)視圖模板的邏輯: layouts/app.blade.php 為布局模板异逐,其他模板都繼承該模板捶索。

    • 最后我們“漢化”這些視圖
      • home.blade.php,你可以自由發(fā)揮灰瞻,展示一個(gè)好看的主頁腥例,這是我的
      @extends('layouts.app')
      
      @section('content')
      <div class="container">
          <div class="row justify-content-center">
              <div class="col-md-8">
                  <div class="card">
                      <div class="card-header">歡迎辅甥!這里是 “那就遠(yuǎn)走” 的個(gè)人博客</div>
      
                      <div class="card-body">
                          如無牽掛,那就遠(yuǎn)走燎竖。
      
                          {{--  這里等下要添加一個(gè)跳轉(zhuǎn)到展示文章列表頁面的按鈕  --}}
                      </div>
                  </div>
              </div>
          </div>
      </div>
      @endsection
      
      • ../layouts/app.blade.php & ../auth/login.blade.php & register.blade.php
      # 首先布局模板我們需要把 brand 登陸璃弄、注冊這些東西改一改
      {{ config('app.name', 'Laravel') }} => 我的博客 //注意這里有一個(gè) config('app.name') 該函數(shù)其實(shí)是讀取的 /.env 里的 APP_NAME 值,且默認(rèn)值為 'Laravel' 构回,也就是說夏块,你改 APP_NAME 也可以改這里顯示的值,不過我嫌麻煩纤掸,直接查找替換了拨扶。
      {{ __('Login') }} => 登陸
      {{ __('Register') }} => 注冊
      {{ __('Logout') }} => 退出
      
      # 然后登陸模板:
      {{ __('Login') }} => 登陸
      {{ __('E-Mail Address') }} => 郵箱
      {{ __('Password') }} => 密碼
      {{ __('Remember Me') }} => 記住我
      然后我們把 ForgetPassword 那個(gè)按鈕給干掉吧(這個(gè)找回密碼的功能需要一個(gè)SMTP服務(wù)的郵箱才能實(shí)現(xiàn),現(xiàn)在暫時(shí)不弄)
      
      # 然后注冊模板
      {{ __('Register') }} => 注冊
      {{ __('Name') }} => 昵稱(用戶名)
      {{ __('Confirm Password') }} => 密碼確認(rèn)
      
      # 有可能有說漏的茁肠,反正自己看著頁面上的英文查找替換成中文就可以了。
      

第二階段總結(jié)

  • 我們使用一條命令就實(shí)現(xiàn)了用戶操作的相關(guān)功能缩举。
  • 但是這條命令生成的視圖是英文的垦梆,所以需要我們改成中文。
  • 這條命令主要是 生成了一組用戶操作的控制器+主頁控制器(其實(shí)還有中間件)仅孩,生成了2條路由托猩,生成了一組視圖。

第三階段_1: 路由辽慕、模型吐辙、視圖茉继、控制器詳解。

  • 如果你完全熟悉MVC架構(gòu),可以跳過這一步屁商。
  • 這里用大白話解釋:
    • 路由: /routes/web.php 瀏覽器中輸入的地址,比如定義 Route::get('home', 'HomeController@home') => 即表示蔬螟,你輸入 "http://localhost/blog/public/home" 是以GET的請求方式去請求 HomeController 的 home() 方法职辨。
    • 模型: /app/ 一個(gè)模型對應(yīng)數(shù)據(jù)庫中的一張數(shù)據(jù)表。(注意大小寫和單復(fù)數(shù)镜撩,模型:Model => 數(shù)據(jù)表:models)
    • 視圖: /resources/views/ 視圖就是普通的html模板预柒,它等待控制器通過 return view() 調(diào)用和渲染它,最終展示給網(wǎng)站訪客袁梗。
    • 控制器: /app/Http/Controllers/ 處理數(shù)據(jù)宜鸯、調(diào)用模型、簡單地操作數(shù)據(jù)庫遮怜、渲染視圖...淋袖,都由它完成。
    • 總結(jié) => 路由定義在瀏覽器中訪問某控制器中某方法的地址锯梁,控制器完成一系列操作:如果需要操作數(shù)據(jù)庫适贸,需要調(diào)用模型灸芳,每一個(gè)模型對應(yīng)一張表。如果需要顯示數(shù)據(jù)拜姿,則需要找到框架內(nèi)指定位置的視圖烙样,對它完成渲染。

第三階段_2:資源路由蕊肥、在資源控制器中完成對博客的增刪改查谒获。

我們寫的程序,除了前臺(tái)好看的界面壁却,就是后臺(tái)的程序批狱,而后臺(tái)的程序無非就是“增刪改查”以及“花式增刪改查”罷了。
因此展东,仔細(xì)想想赔硫,對于一張數(shù)據(jù)表的操作,我們通常就需要這些行為:1盐肃、一個(gè)分頁展示所有數(shù)據(jù)的列表 2爪膊、一個(gè)添加數(shù)據(jù)的功能 3、一個(gè)編輯數(shù)據(jù)的功能 4砸王、一個(gè)顯示單條數(shù)據(jù)詳細(xì)信息的功能 5推盛、一個(gè)刪除功能。

  • 創(chuàng)建一個(gè)資源控制器谦铃,一次性幫我們生成能實(shí)現(xiàn)上面5個(gè)功能的方法 php artisan make:controller BlogController --resource --model=Blog ( --resouce生成的控制器為資源控制器即自帶 CURD增刪改查 所有方法的控制器 ) ( --model 是讓生成的控制器在參數(shù)列表中自動(dòng)幫我們完成依賴注入生成實(shí)際變量 )

  • 根據(jù) 三_1 階段的說法耘成,我們其實(shí)需要設(shè)置很多路由,來對應(yīng)生成的 BlogController 下的各種方法驹闰,Laravel已經(jīng)幫我們想到了所以它給我們提供了這樣一種方法配置路由瘪菌,編輯 /routes/web.php ,在最后面添加這么一句 Route::resource('blog', 'BlogController');

  • 有一個(gè)命令可以看到當(dāng)前所有生效的路由 php artisan route:list ,控制臺(tái)自動(dòng)彈出的表格中嘹朗,Method 表示 請求方法控嗜,即
    Route::這里的方法() ,URI 表示 請求地址骡显,即 Route::action('這里就是uri')疆栏, name 表示 路由別名,可以通過 Route::action('uri', 'Controller@function')->name('這里可以定義路由別名')惫谤。

  • 你會(huì)發(fā)現(xiàn)壁顶,有7條關(guān)于 blog 的路由,這就是 Route::resource('blog', 'BlogController') 幫我們生成的溜歪。(5個(gè)功能7條是因?yàn)?添加和編輯多了2條載入視圖的路由)

  • 完成增刪改查吧: 首先完成 BlogController@index : 展示列表

    • 先來個(gè)入口鏈接若专,打開 home.blade.php
    {{--  上面說過這里會(huì)添加一個(gè)按鈕  --}}
    
    <a href="{{ route('blog.index') }}" class="btn btn-lg btn-block btn-primary">點(diǎn)擊這里查看我的博客</a>
    
    • 編輯 BlogController@index => 這里還是再提醒一下吧,這是說 BlogController 的 index() 方法蝴猪〉魉ィ控制器文件都在 app\Http\Controllers 中
    <?php
    namespace App\Http\Controllers;
    use App\Blog; //這里是使用命令創(chuàng)建控制器時(shí)膊爪,通過 --model=Blog 自動(dòng)幫我們生成的
    use Illuminate\Http\Request;
    
    class BlogController extends Controller
    {
        public function index()
        {
            // 查詢數(shù)據(jù),并且讓查詢結(jié)果是一個(gè)可分頁對象
            $blogs = Blog::orderBy('created_at', 'desc') // 調(diào)用 Blog模型 的靜態(tài)方法 orderBy('根據(jù)created_at字段', '倒敘排序')
                ->paginate(6); // -> 鏈?zhǔn)讲僮鳎簆aginate(6) 即數(shù)據(jù)沒頁6條
            // 跳轉(zhuǎn)到視圖并傳值
            return view('blog.index', [ //第一個(gè)參數(shù)是說嚎莉,視圖模板是 /resources/views/blog/index.blade.php
                'blogs' => $blogs, //這里是說米酬,我們給視圖傳遞一個(gè)叫 $'blogs'的變量,值是前面我們查詢的數(shù)據(jù)趋箩,也叫$blogs赃额。
            ]); // view() 的第二參數(shù)也可以使用 view(..., compact('blogs'))
        }
    
    • 此時(shí)刷新頁面當(dāng)然會(huì)報(bào)錯(cuò)了,因?yàn)槲覀兊囊晥D還不存在叫确,新建文件夾 /resources/views/blog/index.blade.php
    @extends('layouts.app')
    
    @section('content')
    <div class="container">
        <div class="row justify-content-center">
            <div class="card">
                <div class="card-header">這是頁面小標(biāo)題</div>
    
                <div class="card-body">
                    這里是內(nèi)容
                </div>
            </div>
        </div>
    </div>
    
    @endsection
    

    這就是我們所有頁面的布局跳芳,可以復(fù)制一份,作為模板竹勉。

    • 完成視圖里面的內(nèi)容
    <div class="container">
        <div class="row justify-content-center">
            <div class="card">
                <div class="card-header">文章列表</div>
    
                <div class="card-body">
                    <table class="table table-hover table-bordered">
                        <thead class="bg-info">
                            <tr>
                                <th>文章標(biāo)題</th>
                                <th>發(fā)布時(shí)間</th>
                                <th>相關(guān)操作</th>
                            </tr>
                        </thead>
                        <tbody>
                            {{-- 這里通過 @foreach 遍歷數(shù)據(jù) --}} @foreach ($blogs as $blog)
                            <tr>
                                <td>{{ $blog->title }}</td>
                                <td>{{ $blog->created_at }}</td>
                                <td></td>
                            </tr>
                            @endforeach
                        </tbody>
                        <tfoot>
                            {{-- 這里通過 $blogs->links() 來顯示分頁按鈕 --}} {{ $blogs->links() }}
                        </tfoot>
                    </table>
                </div>
            </div>
        </div>
    </div>
    
    • 完成文章添加 添加入口鏈接飞盆, ../layouts/app.blade.php
    {{-- route('路由別名') 在視圖上就是一個(gè)指向 BlogController@create 的鏈接 --}}
    <a href="{{ route('blog.create') }}" class="dropdown-item"> 添加文章 </a>
    
    • 完成文章的添加 BlogController@create
    public function create()
    {
        return view('blog.create'); //載入視圖
    }
    
    • 編輯視圖 重點(diǎn):表單中添加@csrf告訴框架,這是我們自己的表單次乓,不用擔(dān)心csrf跨站請求偽造的攻擊
    @extends('layouts.app')
    
    @section('content')
    <div class="container">
        <div class="row justify-content-center">
            <div class="card">
                <div class="card-header">添加文章</div>
    
                <div class="card-body">
                    {{--  from.method="POST" action="通過 route()函數(shù)讀取路由別名 " --}}
                    <form method="POST" action="{{ route('blog.store') }}">
                        {{--  聲明 csrf 令牌  --}}
                        @csrf
                        <div class="form-group">
                            <label for="title">文章標(biāo)題</label>
                            <input type="text" class="form-control" id="title" placeholder="請輸入文章標(biāo)題" name="title">
                        </div>
                        <div class="form-group">
                            <label for="content">文章內(nèi)容</label>
                            <textarea id="content" cols="30" rows="10" class="form-control" name="content"></textarea>
                        </div>
                        <button class="btn btn-primary" type="submit">發(fā)布新文章</button>
                    </form>
                </div>
            </div>
        </div>
    </div>
    
    @endsection
    

    所謂跨站請求偽造吓歇,可以理解為來自于其他ip的表單,惡意請求我們的服務(wù)器檬输。Laravel提供了一種防范這種攻擊的手段,即將自己的路由隱藏起來匈棘,只有帶有 @csrf 聲明的表單可以找得到接收表單信息的路由

    • 編輯 BlogController@store
    public function store(Request $request) //這里的 $request 是通過依賴注入的方法實(shí)例化的 Request 類的對象丧慈,包含的有所有請求的信息
    {
        // 我們只需要調(diào)用 Blog模型 的靜態(tài)方法 create() 插入 $request->post() 數(shù)據(jù)即可
        $blog = Blog::create($request->post()); //改方法的返回值是新插入的數(shù)據(jù)生成的對象
        // redirect() 頁面重定向
        return redirect()->route('blog.show', $blog); // 這里我們將 $blog 作為參數(shù)請求 BlogController@show 
    }
    
    • 回到頁面,點(diǎn)擊提交主卫,會(huì)發(fā)現(xiàn)報(bào)錯(cuò)了逃默,Laravel是一個(gè)極其注重安全的框架,用戶能修改哪些字段簇搅,必須要在模型文件中聲明完域,因此打開 app\Blog.php 模型文件
    // 可填字段白名單
    protected $fillable = [
        'title', 'content'
    ];
    
    • 再次提交,頁面一片空白瘩将,是因?yàn)槲覀兊?BlogController@show 方法還沒有寫吟税,不過你可以注意到地址欄已經(jīng)發(fā)生了改變。

    • 完成 show 方法

    public function show(Blog $blog) //這里已經(jīng)通過依賴注入的形式幫我們實(shí)例化了 $blog
    {
        return view('blog.show', [
            'blog' => $blog, //直接將$blog傳給視圖進(jìn)行渲染
        ]);
    }
    
    • 新建 ../blog/show.blade.php
    @extends('layouts.app')
    
    @section('content')
    <div class="container">
        <div class="row justify-content-center">
            <div class="card">
                <div class="card-header">文章詳情</div>
    
                <div class="card-body">
                    <h1 class="text-center">{{ $blog->title }}</h1>
    
                    <p>發(fā)布時(shí)間<small>{{ $blog->created_at }}</small></p>
    
                    <hr>
    
                    <p> {{ $blog->content }} </p>
                </div>
            </div>
        </div>
    </div>
    
    @endsection
    
    • 刷新頁面姿现,文章就顯示出來了肠仪。

    • 完成我們的編輯入口鏈接: 在 ../blog/index.blade.php & show.blade.php 中合理的位置添加一個(gè)編輯按鈕

    <a href="{{ route('blog.edit', $blog->id) }}" class="btn btn-info">編輯文章</a>
    
    • 完成 BlogController@edit
    public function edit(Blog $blog)
    {
        return view('blog.edit', [
            'blog' => $blog,
        ]);
    }
    
    • 完成視圖 重點(diǎn):action聲明文章編號(hào),根據(jù)路由要求action在表單中使用@method偽造請求動(dòng)作類型
    @extends('layouts.app')
    
    @section('content')
    <div class="container">
        <div class="row justify-content-center">
            <div class="card">
                <div class="card-header">編輯文章</div>
    
                <div class="card-body">
                    {{-- action需要聲明當(dāng)前編輯的文章編號(hào)$blog->id --}}
                    <form method="POST" action="{{ route('blog.update', $blog->id) }}">
                        {{--  聲明 csrf 令牌  --}}
                        @csrf
                        {{--  偽造 PATCH 方法  --}}
                        @method("PATCH")
                        <div class="form-group">
                            <label for="title">文章標(biāo)題</label>
                            <input type="text" class="form-control" id="title" placeholder="請輸入文章標(biāo)題" name="title" value="{{ $blog->title }}">
                        </div>
                        <div class="form-group">
                            <label for="content">文章內(nèi)容</label>
                            <textarea id="content" cols="30" rows="10" class="form-control" name="content">{{ $blog->content }}</textarea>
                        </div>
                        <p>發(fā)表于<small>{{ $blog->created_at }}</small></p>
                        <p>修改于<small>{{ $blog->updated_at }}</small></p>
                        <button class="btn btn-primary" type="submit">確認(rèn)編輯</button>
                    </form>
                </div>
            </div>
        </div>
    </div>
    
    @endsection
    
    • 完成 BlogController@update
    public function update(Request $request, Blog $blog)
    {
        $blog->update($request->post()); //調(diào)用 $blog對象->update(更新數(shù)據(jù)組成的數(shù)組) 更新
        return redirect()->route('blog.show', $blog);
    }
    
    • 完成刪除功能 在 index.blade.php 和 show.blade.php 合理的位置插入刪除按鈕
    <a href="javascript:deleteConfirm({{ $blog->id }});" class="btn btn-danger btn-sm">刪除文章</a>
                                
    {{--  因?yàn)閯h除也需要 csrf 令牌認(rèn)證备典,所以弄個(gè)表單  --}}
    <form method="POST" action="{{ route('blog.destroy', $blog->id) }}" id="delete-blog-{{ $blog->id }}">
        @csrf
        {{--  這里偽造DELETE請求  --}}
        @method("DELETE")
    </form>
    
    • “刪除文章” 按鈕其實(shí)是調(diào)用了一個(gè) js 函數(shù)异旧,我們在 ../layousts/app.blade.php 中完成
    <script>
        function deleteConfirm(id) {
            var confirm = window.confirm('確認(rèn)要?jiǎng)h除這篇文章嗎?');
            if(confirm === true) {
                $("#delete-blog-" + id).submit(); //提交表單
            }else {
                window.alert('你選擇不刪除提佣!');
            }
        }
    </script>
    
    • 完成 BlogController@delete 方法
    public function destroy(Blog $blog)
    {
        $blog->delete();
        return redirect()->route('blog.index'); //跳轉(zhuǎn)到首頁
    }
    
    • 增刪改查完成吮蛹。
  • 完善和優(yōu)化

    • 首先無論增刪改查操作荤崇,成功后我們沒有任何提示,我們使用 session 閃存方法消息吧:

      • 新建組件視圖文件夾 /resources/views/components/
      • 然后新建一個(gè)組件視圖 _message.blade.php => 組件視圖我們都用_下劃線開頭
      <div class="container">
          {{--  遍歷 success danger 這兩個(gè)我們等會(huì)會(huì)在 session->flash() 方法中設(shè)置的"key"  --}}
          @foreach (['success', 'danger'] as $msg)
              {{--  當(dāng)key存在的時(shí)候潮针,證明我們給 session flash 閃存里面裝載了一次提示信息术荤,那么就顯示提示信息  --}}
              @if (session()->has($msg)) 
                  <div class="alert alert-{{ $msg }}">
                      <ul>
                          <li>{{ session()->get($msg) }}</li>
                      </ul>
                  </div>
              @endif
          @endforeach
      </div>
      
      • 在 ../layousts/app.blade.php 中導(dǎo)入該組件 重點(diǎn):@include 導(dǎo)入html片段
      {{--  在導(dǎo)航下面,內(nèi)容上面導(dǎo)入  --}}
      @include('components._message')
      
      • 編輯 BlogController 里的各種方法然低,在執(zhí)行成功某些方法時(shí)喜每,頁面重定向前,裝載閃存雳攘。以刪除舉例
      $blog->delete();
      session()->flash('success', '刪除文章成功带兜!'); //裝載session閃存
      return redirect()->route('blog.index');
      
    • 然后有個(gè)問題,就是在于吨灭,我們這是一個(gè)個(gè)人博客刚照,所以只有我們自己可以對博客文章進(jìn)行增刪改,而用戶只可以進(jìn)行查看喧兄。因此我們需要:

      • 使用構(gòu)造函數(shù)調(diào)用 auth中間件 來排除沒有登陸的用戶查看文章詳情: 編輯 BlogController
      public function __construct()
      {
          $this->middleware('auth')->except('index');
      }
      
      • 在 新增create无畔、編輯edit、和刪除方法中加入一次用戶認(rèn)證吠冤,以 create 方法舉例
      // 因?yàn)楸容^簡單浑彰,所以我們不用Policy進(jìn)行認(rèn)證,我會(huì)在以后的教程里面教大家如何使用Policy策略進(jìn)行權(quán)限認(rèn)證
      // 這里我們就使用判斷當(dāng)前用戶在數(shù)據(jù)表中信息的主鍵id是不是1即可(因?yàn)槲覀冊赟eeder里面把編號(hào)為1的用戶設(shè)置為了可用的管理員賬號(hào))
      
      // 1拯辙、在代碼開頭引用 Auth
      
      // 2郭变、在方法內(nèi)先判斷一下是不是 1號(hào)用戶
      if(Auth::user()->id != 1) { // Auth::user() 獲取當(dāng)前用戶信息 -> id獲取屬性id(主鍵)
          session()->flash('danger', '抱歉,只有博主才可以新增文章涯保!');
          return redirect()->back();
      }
      
  • 針對博客的增刪改查在這里就結(jié)束了诉濒。

第三階段總結(jié)

  • 我們使用命令創(chuàng)建了一個(gè) “資源控制器”
  • 我們在 /routes/web.php 定義了一條資源路由
  • 我們使用 BlogController 中的7個(gè)方法完成了對 博客文章 的 CURD(增刪改查)操作。
  • 我們優(yōu)化了一下體驗(yàn)夕春,使用 session()->flash() 裝載閃存信息未荒,用一個(gè)組件html片段加載信息,最后用@include()在模板上加載這個(gè)html組件及志。
  • 我們最后增加了一個(gè)簡單的權(quán)限認(rèn)證片排,判斷進(jìn)行增刪改的用戶是不是管理員,不是管理員則不允許操作速侈,直接裝載一條錯(cuò)誤提示閃存划纽,然后返回。

第四階段 評(píng)論功能

  • 新建一個(gè)評(píng)論資源控制器 php artisan make:controller CommentController --model=Commment
  • 新增一條資源路由锌畸,但只支持發(fā)表 /routes/web.php Route::resource('comment', 'CommentController', ['only' => 'store']);

其實(shí)我們可以定義一條 Route::post('comment', 'CommentController@store') 路由勇劣,但是為什么要寫資源路由呢?因?yàn)槲乙嬖V你資源路由可以用 ['onlu'=>'操作'] 讓其只支持一種操作:)

  • 在文章詳情頁面下方增加一個(gè)表單 show.blade.php
<form method="POST" action="{{ route('comment.store') }}">
    @csrf
    <input type="hidden" name="user_id" value="{{ Auth::user()->id }}">
    <input type="hidden" name="blog_id" value="{{ $blog->id }}">

    <div class="form-group">
        <label for="content"></label>
        <textarea id="content" class="form-control" cols="30" rows="10" name="content">您對這篇文章有什么看法呢?</textarea>
    </div>
    <button class="btn btn-primary" type="submit">發(fā)表評(píng)論</button>
</form>
  • 編輯 CommentController@store
public function store(Request $request)
{
    Comment::create($request->post());
    session()->flash('success', '評(píng)論成功比默!');
    return redirect()->back();
}
  • 提交評(píng)論出錯(cuò)了幻捏,又忘了寫可填字段白名單,編輯模型 app\Comment
protected $fillable = [
    'content', 'user_id', 'blog_id'
];
  • 展示評(píng)論
    • 首先我們需要確定 Blog 和 Comment 的關(guān)系 => Blog 1:n Comment “一篇博客有多個(gè)評(píng)論”
    • 我們來綁定他們的關(guān)系
      • app\Blog.php
      // 綁定1:n關(guān)系
      public function comments() {
          return $this->hasMany('App\Comment'); // 1 hasMany n
      }
      
      • app\Comment.php
      public function blog() {
          return $this->belongsTo('App\Blog'); // n belongsTo 1
      }
      
    • 然后通過他們的關(guān)系命咐,我們可以在 BlogController@show 方法中調(diào)用 $blog->comments 來獲取屬于這篇文章的評(píng)論
    // 查詢評(píng)論
    $comments = $blog->comments;
    // 視圖渲染
    return view('blog.show', [
        'blog' => $blog,
        'comments' => $comments, //把評(píng)論也傳過去
    ]);
    
    • 在視圖層遍歷評(píng)論 show.blade.php
    <h3>評(píng)論</h3>
    <ul>
        @foreach ($comments as $comment)
            <li><small>{{ $comment->userName() }} 評(píng)論說:</small>“ {{ $comment->content }} ”</li>
        @endforeach
    </ul>
    
    • 注意我們調(diào)用了 $comment->userName() 方法篡九,現(xiàn)在沒有,所以我們再 app\Comment.php 模型中完成
    use App\User; //引用模型
    
    // 根據(jù) user_id 獲取用戶名
    public function userName() {
        return User::find($this->user_id)->name; //這里通過當(dāng)前對象的 user_id 獲取 user對象醋奠, 然后指向->name屬性
    }
    
  • 評(píng)論驗(yàn)證

在博客中榛臼,我們就沒有使用驗(yàn)證,那是因?yàn)轫?xiàng)目定位是一個(gè)個(gè)人博客窜司,能夠操縱博客增刪改的只有我們自己沛善。而評(píng)論則是只要有人注冊賬號(hào),就可以評(píng)論了塞祈,所以我們應(yīng)該對評(píng)論進(jìn)行一些校驗(yàn)以防惡意攻擊金刁。

  • 新建一個(gè)請求Request php artisan make:request CommentRequest

  • 新建的請求位于 app\Http\Requests\ 下,編輯 CommentRequest

    // 1议薪、 開啟授權(quán)
    public function authorize()
    {
        return true; //如果返回false則所有請求都無法生效尤蛮,會(huì)告訴你沒有授權(quán)(其實(shí)在這里面我們是需要去進(jìn)行判斷的,但是這里的邏輯很簡單:只有登陸才能查看文章詳情斯议,才能看到文章詳情下面發(fā)表評(píng)論的表單产捞,才能發(fā)表評(píng)論。)所以我們這里直接 return true;
    }
    
    // 2哼御、 編輯規(guī)則
    public function rules()
    {
        return [
            'content' => 'required|min:15|max:100', //這里你可以定義規(guī)則我的是:必填坯临、最少15字、最多100字
        ];
    }
    
    • 在 CommentController@store 方法的參數(shù)列表中通過 CommentRequest 構(gòu)造 $request艇搀, 自動(dòng)完成校驗(yàn)
    public function store(CommentRequest $request) // 這將 Request 改成 CommentRequest 就會(huì)自動(dòng)調(diào)用 CommentRequest@rules 來校驗(yàn)請求的數(shù)據(jù)了
    {
        Comment::create($request->post());
        session()->flash('success', '評(píng)論成功尿扯!');
        return redirect()->back();
    }
    
    • 優(yōu)化視圖 show.blade.php
    {{-- 樣式里面加一個(gè)判斷求晶,判斷是否有關(guān)于content的錯(cuò)誤有的話給樣式給文本域加一個(gè)紅邊邊 --}}
    <textarea id="content" class="form-control {{ $errors->has('content') ? ' is-invalid' : '' }}" cols="30" rows="10" name="content">你對文章有什么看法呢焰雕?</textarea>
    
    {{-- 如果有錯(cuò)誤,再顯示一個(gè)小的錯(cuò)誤提示信息 --}}
    @if ($errors->has('content'))
        <span class="invalid-feedback">
            <strong>{{ $errors->first('content') }}</strong>
        </span>
    @endif
    
    • 此時(shí)提交表單芳杏,左下角會(huì)提醒你 “內(nèi)容不能為空”矩屁,如果你想改“內(nèi)容兩個(gè)字”,可以打開 /resources/lang/zh-CN/validation.php
    'content' => '內(nèi)容', //這里就是配置字段的中文名爵赵,你把它改成評(píng)論即可吝秕。
    
    • 有時(shí)候文章過長,導(dǎo)致提交了空幻,往下拉才看得到文本域變紅烁峭,所以我們需要新建一個(gè)錯(cuò)誤組件../components/_error.blade.php
    {{--  判斷是否有錯(cuò)誤  --}}
    @if (count($errors) > 0)
        <div class="alert alert-danger">
            {{--  遍歷所有錯(cuò)誤  --}}
            @foreach ($errors->all() as $error)
                <ul>
                    {{--  打印錯(cuò)誤  --}}
                    <li> {{ $error }}</li>
                </ul>
            @endforeach
        </div>
    @endif
    
    • 然后在 show.blade.php 中引用 @include('components._error')

第四階段總結(jié)

  • 我們依然創(chuàng)建資源控制器,但是在路由中使用['only'=>'store'] 讓資源路由只暴露指向 CommentController@store 的路由
  • 我們學(xué)會(huì)了通過hasMany() & belongsTo()綁定模型之間的1:n關(guān)系。然后通過文章->評(píng)論+s;的方法直接獲取了屬于某篇文章的所有評(píng)論约郁。
  • 我們學(xué)會(huì)了創(chuàng)建請求Request缩挑,并且在它的內(nèi)部配置驗(yàn)證規(guī)則,在控制器層中通過依賴注入的形式驗(yàn)證數(shù)據(jù)鬓梅。
  • 一旦表單提交的數(shù)據(jù)不符合 Request@rules Laravel會(huì)自動(dòng)幫我們生成一個(gè)叫 $errors 的數(shù)組供置,它存放著所有的錯(cuò)誤信息, 我們在視圖上通過判斷它是否有 content 字段來判斷是否是表單提交的評(píng)論有問題绽快,然后修改文本域的樣式并且在下方用一個(gè)小的提示span顯示錯(cuò)誤提示信息
  • 錯(cuò)誤提示信息顯示的是“內(nèi)容 怎么怎么樣...”芥丧,我們想把“內(nèi)容”改成評(píng)論只需要修改中文語言包下的validation.php中的'content'字段的別名即可。

第五階段 最后總結(jié)

  • 想讓項(xiàng)目上線坊罢,也許你需要
    • 更好看的html排版
    • 重新執(zhí)行一次 php artisan migrate:rollback
    • 權(quán)限認(rèn)證太水了续担。你需要學(xué)習(xí)使用 Policy 來進(jìn)行更安全和全面的權(quán)限認(rèn)證。

也許文字很多艘绍,但是真正的代碼可能只有不到100行赤拒,你如果熟練掌握,可能不需要30分鐘诱鞠,甚至10分鐘挎挖,你就可以開發(fā)出這樣一個(gè)博客了。

  • 視圖方面
    • 我們有通過 auth 生成的模板
    • Laravel 自帶的 bootstrap4 + jquery
    • 所以我們解決了css和js的問題 => 我們只是寫了一個(gè) “確認(rèn)刪除” 的前端代碼
  • 數(shù)據(jù)庫方面
    • 我們有 /database/ 下提供的 3套解決方案 Migration / Factory / Seeder 來幫我們解決數(shù)據(jù)庫管理的問題
    • 因?yàn)樯厦娴慕鉀Q方案航夺,我們甚至只寫了 建用戶蕉朵、建表、授權(quán)3條 數(shù)據(jù)庫操作語句阳掐。
  • 路由方面
    • Auth 自動(dòng)幫我們生成了用戶操作相關(guān)路由
    • 我們使用資源路由來映射一個(gè) CURD 控制器
  • 控制器和模型方面始衅,通過命令生成的所有類文件,都幾乎幫我們寫好了缭保,我們只需要完成里面的邏輯汛闸。
  • 當(dāng)然,我們還有 Request 請求認(rèn)證 Policy 策略控制等等一些列的特性沒有學(xué)習(xí)艺骂,我們也只使用了一次composer诸老,其實(shí)在開發(fā)Laravel時(shí),我們還可以使用非常多的钳恕,支持Laravel的别伏,完善的輪子可以利用。

現(xiàn)在請告訴我忧额,它是否配得上 “優(yōu)雅” 的兩字厘肮?:)

希望大家可以喜歡、學(xué)習(xí)和推廣Laravel睦番。如果您愿意付出比學(xué)習(xí)thinkphp5多0.01分的努力类茂,我想這個(gè)框架是非常簡單的。

如果您依然討厭它的龐大,我向您推薦 Lumen 框架巩检。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末恬涧,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子碴巾,更是在濱河造成了極大的恐慌溯捆,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,968評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件厦瓢,死亡現(xiàn)場離奇詭異提揍,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)煮仇,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門劳跃,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人浙垫,你說我怎么就攤上這事刨仑。” “怎么了夹姥?”我有些...
    開封第一講書人閱讀 153,220評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵杉武,是天一觀的道長。 經(jīng)常有香客問我辙售,道長轻抱,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,416評(píng)論 1 279
  • 正文 為了忘掉前任旦部,我火速辦了婚禮祈搜,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘士八。我一直安慰自己容燕,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評(píng)論 5 374
  • 文/花漫 我一把揭開白布婚度。 她就那樣靜靜地躺著蘸秘,像睡著了一般。 火紅的嫁衣襯著肌膚如雪陕见。 梳的紋絲不亂的頭發(fā)上秘血,一...
    開封第一講書人閱讀 49,144評(píng)論 1 285
  • 那天味抖,我揣著相機(jī)與錄音评甜,去河邊找鬼。 笑死仔涩,一個(gè)胖子當(dāng)著我的面吹牛忍坷,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 38,432評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼佩研,長吁一口氣:“原來是場噩夢啊……” “哼柑肴!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起旬薯,我...
    開封第一講書人閱讀 37,088評(píng)論 0 261
  • 序言:老撾萬榮一對情侶失蹤晰骑,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后绊序,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體硕舆,經(jīng)...
    沈念sama閱讀 43,586評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,028評(píng)論 2 325
  • 正文 我和宋清朗相戀三年骤公,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了抚官。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,137評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡阶捆,死狀恐怖凌节,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情洒试,我是刑警寧澤倍奢,帶...
    沈念sama閱讀 33,783評(píng)論 4 324
  • 正文 年R本政府宣布,位于F島的核電站垒棋,受9級(jí)特大地震影響娱挨,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜捕犬,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,343評(píng)論 3 307
  • 文/蒙蒙 一跷坝、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧碉碉,春花似錦柴钻、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至蜡吧,卻和暖如春毫蚓,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背昔善。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評(píng)論 1 262
  • 我被黑心中介騙來泰國打工元潘, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人君仆。 一個(gè)月前我還...
    沈念sama閱讀 45,595評(píng)論 2 355
  • 正文 我出身青樓翩概,卻偏偏與公主長得像牲距,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子钥庇,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,901評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容