Laravel8 学习笔记

1,318 阅读4分钟

写在最前面

因为一次项目的机会,接触到了 laravel 。因为之前一直用的是 ThinkPHP ,所以发现二者很相似,至少初步上手会比较容易,这里记录下自己在制作中遇到的知识点和小坑,希望可以给需要的朋友有所帮助。 三连谢谢,哈哈哈!

Laravel8 官方中文文档

镜像

composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/(阿里云)
composer config -g repo.packagist composer https://packagist.phpcomposer.com(原版)

马上开始

  1. Composer 安装 https://getcomposer.org/download/
  2. 首次全局安装 laravel 安装器 composer global require laravel/installer
  3. 安装 composer create-project --prefer-dist laravel/laravel 项目名称
  4. 运行 php artisan serve

如果想配合局域网共享访问,可以制定本机ip php artisan serve --host=192.168.1.7。 这样实际访问地址就是 http://192.168.1.7:8000


控制器

  1. 普通 php artisan make:controller Home
  2. 资源 php artisan make:controller Home --resource
  3. API php artisan make:controller api/Home --api

路由

  1. 普通 routes/web.php
use App\Http\Controllers\Home;
Route::get('/', [Home::class, 'index']);
  1. 资源 routes/web.php
use App\Http\Controllers\Home;
Route::resource('/', Home::class);
  1. API routes/api.php
use App\Http\Controllers\api\JsonList;
Route::apiResource('json_list', JsonList::class);

查看所有已注册路由 php artisan route:list

路由分组
  • 单个
Route::middleware(['auth'])->group(function () {
    Route::resource('/store', App\Http\Controllers\Store::class);
    Route::resource('/wine', App\Http\Controllers\Wine::class);
});
  • 多个
Route::group(['prefix' => 'admin', 'middleware' => ['auth']], function () {
    Route::resource('/store', App\Http\Controllers\Store::class);
    Route::resource('/wine', App\Http\Controllers\Wine::class);
});

数据库

  1. 新建表 php artisan make:migration create_users_table
  2. 同步到数据库 php artisan migrate
  3. 刷新提交 php artisan migrate:refresh
数据填充
  1. 设置需要添加的数据 seeders/DatabaseSeeder.php
  2. 刷新提交 php artisan migrate:fresh --seed
  3. learnku.com/docs/larave…

模型

  • php artisan make:model List
  • 允许写入字段,否则无法新增 app/Models/List.php 添加 protected $fillable = ['name','address'];
  • 开启软删除 app/Models/List.php 添加
use Illuminate\Database\Eloquent\SoftDeletes;
{
    // ...
    use SoftDeletes;
}
  • 时间戳纯数字 app/Models/List.php 添加 protected $dateFormat = 'U';
  • 修改器 app/Models/List.php
public function get***Attribute($value)
{
    $this->id;// 调用 id 字段
    return $value;// 最终输出
}
在控制器使用模型
  • 引入
use App\Models\Store as ModelStore;
  • 分页全部数据
$stores = ModelStore::orderBy('id', 'desc')->paginate(10);
return view('store.index', ['stores' => $stores]);
关联查询
  • 模型
class WineAward extends Model
{
    use HasFactory;

    public function wxuser()
    {
        return $this->belongsTo('App\Models\WxUser');
    }

    public function wine()
    {
        return $this->belongsTo('App\Models\Wine');
    }
}
  • 控制器 全部输出
$wineaward = ModelWineAward::find($id)->with(['wxuser','wine'])->get();
  • 控制器 指定内容输出
$wineaward = ModelWineAward::find($id)->with(['wxuser:id,nickname','wine:id,name'])->get();
嵌套关联查询

通过 WineAward 控制器的 wine(),再查询 Wine 控制器的 store()

// WineAward.php
wine.store
  • 模型 WineAward
class WineAward extends Model
{
    use HasFactory;

    public function wxuser()
    {
        return $this->belongsTo('App\Models\WxUser');
    }

    public function wine()
    {
        return $this->belongsTo('App\Models\Wine');
    }
}
  • 模型 Wine
class Wine extends Model
{
    use HasFactory;

    public function store()
    {
        return $this->belongsTo('App\Models\Store');
    }
}
  • 控制器 全部输出
$wineaward = ModelWineAward::find($id)->with(['wxuser:id,nickname','wine:id,name,store_id','wine.store:id,name'])->get();

清空

  1. php artisan config:clear

集合

集合 -- 数组数据的封装 learnku.com/docs/larave…

Laravel Jetstream

整合用户登录和注册,根据官方文档来,没啥大问题。

jetstream.laravel.com/2.x/introdu… learnku.com/docs/larave…

安装
  1. 安装 composer require laravel/jetstream
  2. 个人版 php artisan jetstream:install livewire
  3. 团队版 php artisan jetstream:install livewire --teams
  4. npm install
  5. npm run dev
  6. 本地配置数据同步到数据库 php artisan migrate,如果如果这里有报错,修改 config/database.php 编码
'charset' => 'utf8',
'collation' => 'utf8_general_ci', 
  1. 首次登录注册地址 http://127.0.0.1:8000/register
显示组件

显示 Blade 组件 php artisan vendor:publish --tag=jetstream-views

Blade 组件的位置 resources/views/vendor/

关闭注册等

config/fortify.php

return [
    'features' => [
        // Features::registration(),// 关闭注册
        Features::resetPasswords(),
        // Features::emailVerification(),// 关闭邮箱验证
        Features::updateProfileInformation(),
        Features::updatePasswords(),
        // Features::twoFactorAuthentication([// 关闭添加二次验证
        //     'confirmPassword' => true,
        // ]),
    ],

];
关闭删除账户

config/jetstream.php

    'features' => [
        // Features::termsAndPrivacyPolicy(),
        // Features::profilePhotos(),
        // Features::api(),
        Features::teams(['invitations' => false]),// false 不使用发送邮箱邀请模式
        // Features::accountDeletion(),// 关闭账户删除功能
    ],

];
登录验证码

Laravel8 里的登录页面添加登录的验证码,确实有亿点点复杂,还好搞定了。

验证码插件 github.com/mewebstudio…

  1. 安装 composer require mews/captcha
  2. 配置 config/app.php
    'providers' => [
        // ...
        Mews\Captcha\CaptchaServiceProvider::class,// 验证码
    ]
    
    'aliases' => [
        // ...
        'Captcha' => Mews\Captcha\Facades\Captcha::class,// 验证码
    ]
  1. 显示验证码配置 php artisan vendor:publish 位置 config/captcha.php
  2. 新建 app/Actions/Fortify/CaptchaValidation.php
<?php

namespace App\Actions\Fortify;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;

class CaptchaValidation
{
    public function __invoke(Request $request, $next)
    {
        Validator::make($request->all(), [
            'captcha' => 'required|captcha'
        ])->validate();

        return $next($request);
    }
}
  1. 配置 app/Providers/JetstreamServiceProvider.php
// 验证码
use Illuminate\Http\Request;
use App\Actions\Fortify\CaptchaValidation;
use Laravel\Fortify\Actions\AttemptToAuthenticate;
use Laravel\Fortify\Actions\EnsureLoginIsNotThrottled;
use Laravel\Fortify\Actions\PrepareAuthenticatedSession;

    public function boot()
    {
        $this->configurePermissions();

        Jetstream::createTeamsUsing(CreateTeam::class);
        Jetstream::updateTeamNamesUsing(UpdateTeamName::class);
        Jetstream::addTeamMembersUsing(AddTeamMember::class);
        Jetstream::inviteTeamMembersUsing(InviteTeamMember::class);
        Jetstream::removeTeamMembersUsing(RemoveTeamMember::class);
        Jetstream::deleteTeamsUsing(DeleteTeam::class);
        Jetstream::deleteUsersUsing(DeleteUser::class);

        // 验证码
        Fortify::authenticateThrough(function (Request $request) {
            return array_filter([
                config('fortify.limiters.login') ? null : EnsureLoginIsNotThrottled::class,
                CaptchaValidation::class,
                AttemptToAuthenticate::class,
                PrepareAuthenticatedSession::class,
            ]);
        });
    }
  1. 登录页面 resources/views/vendor/auth/login.blade.php
<div class="mt-4">
    <x-jet-label for="captcha" value="{{ __('Captcha') }}" />
    <span class="block mt-1 float-right">@php  echo captcha_img('flat'); @endphp</span>
    <x-jet-input id="captcha" class="block mt-1 w-30" type="text" name="captcha" required autocomplete="current-captcha" />
</div>

此外,Mac 下的 PHP不带 freetype ,解决办法就是再安装个 PHP 咯。 然后重启电脑,必定有效。 www.jianshu.com/p/09f3ea8ac…

Voyager

github.com/the-control…

  • 后台管理系统:可添加权限用户,表单自定义,后台入口定义等
  • 第一步:安装 composer require tcg/voyager + composer require barryvdh/laravel-debugbar --dev
  • 第二步:添加数据 php artisan voyager:install
  • 第三步:添加管理员 php artisan voyager:admin your@email.com --create
  • 本番环境清缓存 routes/web.php 添加
    // 手动清空缓存 https://juejin.cn/clear-cache
    Route::get('/clear-cache', function() {
        Artisan::call('cache:clear');
        return "Cache is cleared";
    });
    

如果登录跳转出现bug,可以尝试重复第一步到第三部的操作。

登录验证码
  • 实测只可以使用 V2 reCAPTCHA
  • github.com/seyedmr/voy…
  • www.google.com/recaptcha/a…
  • 国内访问问题 搜索 VoyagerRecaptcha.php 替换 https://www.google.com/recaptcha/api.js
    const CLIENT_API = 'https://www.recaptcha.net/recaptcha/api.js';
    const VERIFY_URL = 'https://www.recaptcha.net/recaptcha/api/siteverify';
    

微信

github.com/overtrue/la…

  • 版本要求 PHP >= 7.4
  • 安装如果失败,更新下 composer 版本 composer self-update
  • 安装 composer require "overtrue/laravel-wechat:^6.0"
  • 貌似必须使用阿里云镜像 composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/
  • 创建配置文件 php artisan vendor:publish --provider="Overtrue\LaravelWeChat\ServiceProvider"
中间件获取用户信息
  1. 路由 routes/web.php
Route::any('/wechat/oauth', [WeChat::class, 'oauth'])->middleware('wechat.oauth');
  1. 控制器 app/Http/Controllers/WeChat.php
public function oauth(){
    return dd(session('wechat.oauth_user.default.raw'));
}
微信分享功能
  1. 控制器 app/Http/Controllers/WeChat.php
public function share(){
        $app = app('wechat.official_account');
        $APIs = ['updateAppMessageShareData', 'updateTimelineShareData', 'onMenuShareTimeline', 'onMenuShareAppMessage'];
        $jssdk = $app->jssdk->buildConfig($APIs, $debug = false, $beta = false, $json = true);
        $config = [
            'title'  => 'title1', // 分享标题
            'desc'   => 'desc1', // 分享描述
            'link'   => url()->current(), // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
            'imgUrl' => '/images/oy.jpeg', // 分享图标
        ];
	return view('wechat.share',[
            'jssdk' => $jssdk,
            'config' => $config,
        ]);
}
  1. 显示 resources/views/wechat/share.blade.php
<script src="http://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
<script>
    wx.config({!!$jssdk!!});
    wx.ready(function () {
        wx.updateAppMessageShareData({ 
            title: '{{$config['title']}}', // 分享标题
            desc: '{{$config['desc']}}', // 分享描述
            link: '{{$config['link']}}', // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
            imgUrl: '{{url('/')}}{{$config['imgUrl']}}', // 分享图标
            success: function () {
                // 设置成功
                alert('updateAppMessageShareData111');
            }
        })
        wx.updateTimelineShareData({ 
            title: '{{$config['title']}}', // 分享标题
            desc: '{{$config['desc']}}', // 分享描述
            link: '{{$config['link']}}', // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
            imgUrl: '{{url('/')}}{{$config['imgUrl']}}', // 分享图标
            success: function () {
                // 设置成功
                alert('updateTimelineShareData222');
            }
        })
        wx.onMenuShareTimeline({ // 即将废弃
            title: '{{$config['title']}}', // 分享标题
            desc: '{{$config['desc']}}', // 分享描述
            link: '{{$config['link']}}', // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
            imgUrl: '{{url('/')}}{{$config['imgUrl']}}', // 分享图标
            success: function () {
                // 设置成功
                alert('onMenuShareTimeline333');
            }
        })
        wx.onMenuShareAppMessage({ // 即将废弃
            title: '{{$config['title']}}', // 分享标题
            desc: '{{$config['desc']}}', // 分享描述
            link: '{{$config['link']}}', // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
            imgUrl: '{{url('/')}}{{$config['imgUrl']}}', // 分享图标
            success: function () {
                // 设置成功
                alert('onMenuShareAppMessage444');
            }
        })
    }); 
</script>

调试

github.com/barryvdh/la…

  1. 安装 composer require barryvdh/laravel-debugbar --dev
  2. 关闭 .env APP_DEBUG=false 或者 config/app.php 'debug' => false
  3. 使用 \Debugbar::info('OY');

请求限制

默认只能 60 次请求,然后返回 429 TOO MANY REQUESTS

  1. 打开 app/Providers/RouteServiceProvider.php
  2. 修改 Limit::perMinute(60) 中的数字

部署到根目录

  1. 网站目录 -> 运行目录 = /public
  2. 伪静态 = thinkphp (因为选项里没有 laravel)

部署到子目录

方法一
  1. http://127.0.0.1/travel/rrm/
  2. 根目录 server.php 改名成 index.php
  3. public/.htaccess
    <IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /travel/rrm/
    RewriteRule ^index\.php$ - [L]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /travel/rrm/index.php [L]
    </IfModule>
    
  4. public/mix-manifest.json
    {
        "/js/app.js": "http://127.0.0.1/travel/rrm/public/js/app.js",
        "/css/app.css": "http://127.0.0.1/travel/rrm/public/css/app.css"
    }
    
  5. php artisan livewire:publish
  6. config/livewire.php
    'asset_url' => 'http://127.0.0.1/travel/rrm',
    
方法二
  1. http://127.0.0.1/travel/rrm/
  2. 浏览器输入 http://127.0.0.1/travel/rrm/public/
  3. 无需配置public/.htaccess,然后456同上

持续更新