Laravel 无疑是一个优秀的Web开发框架,优雅的语法和封装,现成的解决方案,让人无需考虑太多底层的东西。但是,这必须在对框架本身熟悉的前提下,才能游刃有余。即便是老手,没注意看文档,也会栽坑里。
测试环境: Laravel 版本:6.18.35
新增服务提供者不生效
此问题源于 模型的多态关联
,数据库设计时,没有按照 Laravel 约定,设置关联类型字段为字符串,这边设计为整型。必须使用 自定义多态类型
。做一个 morph 映射:设置整数字段的枚举值,映射到数据模型的类名。
例: 评论数据表,为了区分是文章评论,还是视频评论,新增了 commentable_type 字段,0为文章评论,1为视频评论。
下面是官方文档,关于 自定义多态类型 的说明:
不过,你可能希望数据库与应用的内部结构解耦。在这种情况下,可以定义一个 「morph 映射」 来通知 Eloquent 使用自定义名称代替对应的类名:
use Illuminate\Database\Eloquent\Relations\Relation;
Relation::morphMap([
0 => 'App\Post',
1 => 'App\Video',
]);
可以在 AppServiceProvider 的 boot 函数中注册 morphMap,或者创建一个单独的服务提供者
。
不过,这边是 创建一个单独的服务提供者
,但是一直没有生效。排查了许久。最后使用如下命令解决:
php artisan config:cache
因为新增加的服务提供者,根本没有加入到配置列表。通过以上命令才会生效。
配置文件密码包含 #
号
.env
文件中,数据库密码不能使用#
,否则解析的时候#
后面的部分会被当做注释从而导致密码解析错误
解决:用单引号或双引号将密码字符串包裹
DB_PASSWORD="password#1234"
路由解析匹配顺序
正常情况路由列表匹配顺序为:从路由文件,由上往下匹配。
一条路由记录符合,就不再匹配下一条。如下所示:
正确:
Route::get('/posts/create','PostController@create');
Route::get('/posts/{post}','PostController@show');
错误:
Route::get('/posts/{post}','PostController@show');
Route::get('/posts/create','PostController@create');
然而,使用 redirect 方法,重定向路由。实际却是反过来的,与上述经验不符:
Route::get('/', 'HomeController@index');
// 虽然路由表解析顺序是从上往下匹配,但是,下面这段 redirect 要放在 Route::get("/")下面才有效
Route::redirect('/', '/admin/users');
数据迁移
Schema::create("user_coupons", function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedInteger('cost_points')->default(0)->comment('花费积分'); // 不允许为null,默认0
$table->boolean('validate')->nullable()->default(0)->comment('是否有效'); // 允许为null,默认0.
$table->timestamp('used_at')->nullable()->comment('使用时间'); // 允许null, 默认null
$table->timestamp('deleted_at')->nullable(); // 允许null, 默认null
$table->timestamps();
});
定时任务log日志写入失败问题
原因:
宝塔调用 artisan 命令,每天凌晨执行定时任务。
按天切割日志后,artisan 命令,每天首先生成 laravel-{Y-m-d}.log
日志,权限为 root
。
而网站应用,正常以 php-fpm
模式运行。通常是以 www
用户的权限,来生成或读写文件。
所以,命令模式以 root
权限创建 log 文件, web 程序以 www
权限对 log 日志文件写入失败。
解决:
cd /www/wwwroot/league && php artisan schedule:run
改为:
cd /www/wwwroot/league && su www -s /bin/bash -c "php artisan schedule:run"
或者(未验证):
$app->configureMonologUsing(function(Monolog\Logger $monolog) {
$filename = storage_path('logs/laravel-'.php_sapi_name().'.log');
$handler = new Monolog\Handler\RotatingFileHandler($filename);
$monolog->pushHandler($handler);
});
保存数据时,空字符自动转化为 NULL 问题
有一个 ConvertEmptyStringsToNull 中间件,自动将空字符串转为 null。
在 App\Http\Kernel.php 中,注释了这个中间件就好了
App\Http\Kernel.php
......
protected $middleware = [
\App\Http\Middleware\TrustProxies::class,
\App\Http\Middleware\CheckForMaintenanceMode::class,
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
\App\Http\Middleware\TrimStrings::class,
// \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
];
......
数据库版本低于5.7报错
mysql 数据库版本低于5.7时,执行 php artisan migrate
后报错:
PDOException::("SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes")
解决:
在AppServiceProvider添加代码: Schema::defaultStringLength(191);
vim app/Providers/AppServiceProvider.php
use Illuminate\Support\Facades\Schema;
......
public function boot()
{
Schema::defaultStringLength(191);
}
......
Eloquent 默认属性值为空字符串 ( ‘’) 的时候,自动转为 null 的问题 https://learnku.com/laravel/t/35052
详解Laravel设置多态关系模型别名的方式 https://www.jb51.net/article/172181.htm
Laravel 日志权限变成 Root 处理 https://www.phpriji.cn/blog/detail/20180713142308qvpcnu.html
artisan日志-root权限-www不能访问解决办法 https://blog.csdn.net/u013866352/article/details/105402716