写在最前面
因为一次项目的机会,接触到了 laravel 。因为之前一直用的是 ThinkPHP ,所以发现二者很相似,至少初步上手会比较容易,这里记录下自己在制作中遇到的知识点和小坑,希望可以给需要的朋友有所帮助。
三连谢谢,哈哈哈!
Laravel8 官方中文文档
- 首页 learnku.com/docs/larave…
- 控制器 - 资源控制器操作处理 learnku.com/docs/larave…
- 模型 learnku.com/docs/larave…
- 模型关联 learnku.com/docs/larave…
- 表单验证 learnku.com/docs/larave…
- 数据库迁移 - 可用的字段类型 learnku.com/docs/larave…
Blade模板 learnku.com/docs/larave…
镜像
composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/(阿里云)
composer config -g repo.packagist composer https://packagist.phpcomposer.com(原版)
马上开始
Composer安装https://getcomposer.org/download/- 首次全局安装
laravel安装器composer global require laravel/installer - 安装
composer create-project --prefer-dist laravel/laravel 项目名称 - 运行
php artisan serve
如果想配合局域网共享访问,可以制定本机ip php artisan serve --host=192.168.1.7。
这样实际访问地址就是 http://192.168.1.7:8000
控制器
- 普通
php artisan make:controller Home - 资源
php artisan make:controller Home --resource - API
php artisan make:controller api/Home --api
路由
- 普通
routes/web.php
use App\Http\Controllers\Home;
Route::get('/', [Home::class, 'index']);
- 资源
routes/web.php
use App\Http\Controllers\Home;
Route::resource('/', Home::class);
- 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);
});
数据库
- 新建表
php artisan make:migration create_users_table - 同步到数据库
php artisan migrate - 刷新提交
php artisan migrate:refresh
数据填充
- 设置需要添加的数据
seeders/DatabaseSeeder.php - 刷新提交
php artisan migrate:fresh --seed - 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();
清空
php artisan config:clear
集合
集合 -- 数组数据的封装 learnku.com/docs/larave…
Laravel Jetstream
整合用户登录和注册,根据官方文档来,没啥大问题。
jetstream.laravel.com/2.x/introdu… learnku.com/docs/larave…
安装
- 安装
composer require laravel/jetstream - 个人版
php artisan jetstream:install livewire - 团队版
php artisan jetstream:install livewire --teams npm installnpm run dev- 本地配置数据同步到数据库
php artisan migrate,如果如果这里有报错,修改config/database.php编码
'charset' => 'utf8',
'collation' => 'utf8_general_ci',
- 首次登录注册地址
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…
- 安装
composer require mews/captcha - 配置
config/app.php
'providers' => [
// ...
Mews\Captcha\CaptchaServiceProvider::class,// 验证码
]
'aliases' => [
// ...
'Captcha' => Mews\Captcha\Facades\Captcha::class,// 验证码
]
- 显示验证码配置
php artisan vendor:publish位置config/captcha.php - 新建
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);
}
}
- 配置
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,
]);
});
}
- 登录页面
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
- 后台管理系统:可添加权限用户,表单自定义,后台入口定义等
- 第一步:安装
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.jsconst CLIENT_API = 'https://www.recaptcha.net/recaptcha/api.js'; const VERIFY_URL = 'https://www.recaptcha.net/recaptcha/api/siteverify';
微信
- 版本要求
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"
中间件获取用户信息
- 路由
routes/web.php
Route::any('/wechat/oauth', [WeChat::class, 'oauth'])->middleware('wechat.oauth');
- 控制器
app/Http/Controllers/WeChat.php
public function oauth(){
return dd(session('wechat.oauth_user.default.raw'));
}
微信分享功能
- 控制器
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,
]);
}
- 显示
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>
调试
- 安装
composer require barryvdh/laravel-debugbar --dev - 关闭
.envAPP_DEBUG=false或者config/app.php'debug' => false - 使用
\Debugbar::info('OY');
请求限制
默认只能 60 次请求,然后返回 429 TOO MANY REQUESTS
- 打开
app/Providers/RouteServiceProvider.php - 修改
Limit::perMinute(60)中的数字
部署到根目录
- 网站目录 -> 运行目录 =
/public - 伪静态 =
thinkphp(因为选项里没有laravel)
部署到子目录
方法一
http://127.0.0.1/travel/rrm/- 根目录
server.php改名成index.php 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>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" }php artisan livewire:publishconfig/livewire.php'asset_url' => 'http://127.0.0.1/travel/rrm',
方法二
http://127.0.0.1/travel/rrm/- 浏览器输入
http://127.0.0.1/travel/rrm/public/ - 无需配置
public/.htaccess,然后456同上
持续更新