一,代码规范
本文所有项目环境为 mysql5.5 + php 7.3 +nginx(phpstudy)
为了开发方便,这里遵循 约定大于配置 的原则
- 创建全局使用函数,创建文件 app/helpers.php,并且在项目中自动加载。在项目 composer.json 中 autoload 部分里的 files 字段加入该文件即可
{
...
"autoload": {
"files": [
"app/helpers.php"
]
}
...
}
还有一种方法,config/app.php的provider数组中注册服务提供者,暂不讨论
- 不在路由配置文件中使用“闭包路由”,会导致路由缓存不可用。优先使用restful风格的路由
- resource类型的资源路由必须使用复数形式,并优先使用only做白名单过滤
Route::resource('articles', 'ArticlesController', ['only' => ['index', 'show']]);
- 除了 resource 资源路由以外,其他所有路由都 必须 使用 name 方法进行命名
Route::post('users/{id}/follow', 'UsersController@follow')->name('users.follow');
- 所有的数据模型文件,都 必须 存放在:app/Models/ 文件夹中
- 模型类名必须为单数,类文件名也必须为单数。如 app/Models/Article.php,类名为Article
- 数据库表名必须为复数,如 articles,多单词的情况下使用 my_articles 形式
- 数据库表迁移文件名必须为复数,如 2020_08_14_160154_create_topics_table.php
- 数据表填充文件名必须为复数,如 ArticlesTableSeeder.php
- Eloquent Article 模型默认情况下会使用类的「下划线命名法」与「复数形式名称」来作为数
据表的名称生成规则,如Article 数据模型类对应 articles 表,BlogPost 数据模型类对应 blog_posts 表 - 数据表字段命名中,主键必须为 id ,关联的外键必须为 user_id,字段名字必须为last_edit_time 形式
- 控制器名必须为复数,类文件名也必须为复数。如 app\Http\Controllers 中的 ArticlesController.php,类名为ArticlesController
- 局部视图文件 必须 使用 _ 前缀来命名。如 layouts/_header.blade.php
- 绝不使用authorize() 方法来做用户授权,用户授权我们会单独使用 Policy 授权策略来实现
- 所有的自定义命令,都要带上项目的命名空间,如 bbs57:calculate-active-user
- 必须 使用 Carbon 来处理日期和时间相关的操作
- Auth 中间件 必须 书写在控制器的 __construct 方法中,并且 必须 使用 except 黑名单进行过滤,这样新增控制器方法时,默认是安全的
二,主要流程
- 一个功能齐全的模块大概需要以下常用开发流程,实际应用中可以根据需要调整。
1.创建数据库迁移文件
2.执行数据库迁移命令
3.创建相关模型文件
4.创建数据库填充的工厂文件
5.创建数据填充文件
6.在路由文件中创建相关路由
7.创建相关控制器文件
8.创建相关表单请求文件
9.创建模型事件监控器,并注册
10.创建授权策略文件,并注册
11.创建相关视图文件
三,实例
1. 在app目录下 创建helpers.php,并修改 App\Providers\AppServiceProvider,兼容mysql5.5等低版本
public function boot()
{
Schema::defaultStringLength(191);//这行代码作用是设置当前数据库默认字符长度
Carbon::setLocale('zh');//设置时间格式为中文
}
修改config/database.php中 mysql配置
...
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
...
修改时区,在config/app.php中
'locale' => 'zh_CN',
2. 修改模型文件放置目录为app/Models (高版本无需修改)
- a. 将自带的User.php模型文件移入 app/Models目录中,并修改类文件的命名空间为 App\Models
- b. 编辑器全局替换 App\User 替换为 App\Models\User
3. 创建数据库迁移文件
- a. 在命令行创建数据库迁移文件,即数据表的结构生成文件。(注意数据库迁移文件的命名方式,和参数。–create="articles"表示创建的表名字)
php artisan make:migration create_articles_table --create="articles"
- b. 修改刚生成的 2020_08_20_072138_create_articles_table.php 文件
public function up()
{
Schema::create('articles', function (Blueprint $table) {
$table->increments('id');
$table->string('title');
$table->text('content');
$table->integer('user_id')->index();
$table->timestamps();
});
}
- c. 执行迁移
php artisan migrate
生成了articles表
- d. 新增字段
在命令行执行如下代码,添加一个新字段头像avatar,这里的–table表示要修改的表名
php artisan make:migration add_avatar_to_users_table --table=users
修改新增的 迁移文件
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddAvatarToUsersTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('users', function (Blueprint $table) {
$table->string('avatar')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('users', function (Blueprint $table) {
$table->dropColumn('avatar');
});
}
}
执行数据库迁移
php artisan migrate
- e. 修改已有
先composer下载 doctrine/dbal依赖
composer require doctrine/dbal
然后新增更改字段的迁移文件
php artisan make:migration alter_users_table
修改刚生成的迁移文件
public function up()
{
Schema::table('users', function (Blueprint $table) {
$table->string('name', 50)->change();
});
}
执行迁移命令
php artisan migrate
4. 创建模型类
- a. 使用命令行创建模型类
# php artisan help 命令,可以查看帮助文档
php artisan help make:model
php artisan make:model Models/Article
可同时生成迁移文件
php artisan make:model Models/Article -m
5. 创建数据库填充工厂文件
- a. 使用命令行创建工厂文件
php artisan make:factory ArticleFactory
- b. 生成并修改用户表填充工厂文件
php artisan make:factory UserFactory
$factory->define(App\Models\User::class, function (Faker $faker) {
$date_time=$faker->date.' '.$faker->time();
return [
'name' => $faker->name,
'email' => $faker->unique()->safeEmail,
'email_verified_at' => now(),
'password' => '$2y$10$TKh8H1.PfQx37YgCzwiKb.KjNyWgaHb9cbcoQgdIVFlYg7B77UdFm', // secret
'remember_token' => str_random(10),
'created_at' => $date_time,
'updated_at' => $date_time,
];
});
- c. 修改刚生成的工厂文件 database/factories/StatusFactory.php
use Faker\Generator as Faker;
$factory->define(App\Models\Article::class, function (Faker $faker) {
$date_time = $faker->date . ' ' . $faker->time;
//随机生成『小段落』文本
$sentence = $faker->sentence();
return [
'title' => $sentence,
'content' => $faker->text(),
'created_at' => $date_time,
'updated_at' => $date_time,
];
});
6. 创建数据填充文件
- a. 使用命令行创建数据填充文件
php artisan make:seeder ArticlesTableSeeder
- b. 创建用户数据填充文件并修改内容
php artisan make:seeder ArticlesTableSeeder
public function run()
{
$users=factory(User::class)->times(50)->make();
User::insert($users->makeVisible(['password','rember_token'])->toArray());
$user=User::find(1);
$user->name='sangjia';
$user->email='sangjia1990@163.com';
$user->password=bcrypt('123456');
$user->save();
}
- c. 修改刚生成的数据填充文件
public function run()
{
$user_ids = ['1','2','3'];
$faker = app(Faker\Generator::class);
$statuses = factory(Status::class)->times(100)->make()->each(function ($statu
$status->user_id = $faker->randomElement($user_ids);
});
Status::insert($statuses->toArray());
}
- d. 指定要调用的数据填充文件
修改database/seeds/DatabaseSeeder.php文件
public function run()
{
Model::unguard();
$this->call(UsersTableSeeder::class);
$this->call(ArticlesTableSeeder::class);
Model::reguard();
}
d. 执行重置数据并进行数据填充
php artisan migrate:refresh --seed
7. 创建路由
打开 routes/web.php文件
新资源增路由如下
Route::resource('articles', 'ArticlesController');
8. 创建控制器
- a. 使用命令行创建资源型控制器
php artisan make:controller ArticlesController --resource
- b. 给新建的 App\Http\Controllers\ArticlesController 控制器添加中间件
public function __construct()
{
$this->middleware('auth', ['except' => ['index', 'show']]);
}
9. 修改模型文件
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Status extends Model
{
//可修改字段
protected $fillable = ['content'];
public function user()
{ //文章和用户关系为 多对一
return $this->belongsTo(User::class);
}
}
10. 修改控制器文件
public function store(ArticleRequest $request)
{
//注入请求类ArticleRequest,验证请求参数
$topic->fill($request->all());//fill 方法会将传参的键值数组填充到模型的属性中
$topic->user_id = Auth::id();
$topic->save();
session()->flash('success', '发布成功!');
return redirect()->back();
}
public function edit(Article $article)
{
//验证策略权限
$this->authorize('update', $article);
return view('article.create_and_edit', compact('article'));
}
11. 增加表单请求参数验证
- a. 使用命令行生成request验证类
php artisan make:request ArticleRequest
- b. 修改生成的 App\Http\Requests\ArticleRequest 类
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class ArticleRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'title' => 'required|min:2',
'body' => 'required|min:3',
];
}
}
并在控制器中注入使用
public function store(ArticleRequest $request,Topic $topic)
{
.................
}
12. 创建模型事件监控器
- a. 使用命令行创建模型监控器类
php artisan make:observer ArticleObserver --model=Article
新建的监控器类位于app/Observers下
里面包含一些方法,对模型的增删改等操作进行监听触发。retrieved、creating、created、updating、updated、saving、saved、deleting、deleted、restoring、restored。
class TopicObserver
{
public function creating(Topic $topic)
{
//
}
public function updating(Topic $topic)
{
//
}
}
- b. 注册监控器
打开app/Providers/AppServiceProvider.php
在boot方法中注册监控器
public function boot()
{
\App\Models\Article::observe(\App\Observers\ArticleObserver::class);
Schema::defaultStringLength(191);//这行代码作用是设置当前数据库默认字符长度
Carbon::setLocale('zh');//设置时间格式为中文
}
13. 创建授权策略文件
a. 使用命令行创建策略文件
php artisan make:policy ArticlePolicy
b. 修改方法返回布尔值,update,index 等方法对应控制器中的方法
namespace App\Policies;
use App\Models\Article;
use Illuminate\Auth\Access\HandlesAuthorization;
class ArticlePolicy
{
use HandlesAuthorization;
/**
* Create a new policy instance.
*
* @return void
*/
public function __construct()
{
//
}
/*
* 第一个参数默认为当前登录(操作)用户实例,第二个参数则为要进行授权的用户
实例,既为提交过来的数据
*/
public function update(User $currentUser,Article $article)
{
//
return $currentUser->id === $article->user_id;
}
}
c. 设置授权策略以及使用
修改app/Providers/AuthServiceProvider.php
namespace App\Providers;
use Illuminate\Support\Facades\Gate;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
class AuthServiceProvider extends ServiceProvider
{
/**
* The policy mappings for the application.
*
* @var array
*/
protected $policies = [
'App\Model' => 'App\Policies\ModelPolicy',
\App\Models\User::class => \App\Policies\UserPolicy::class,
\App\Models\Article::class => \App\Policies\ArticlePolicy::class,
];
/**
* Register any authentication / authorization services.
*
* @return void
*/
public function boot()
{
$this->registerPolicies();
//
}
}
在控制其中使用。
public function update(ArticleRequest $request, Article $article)
{
$this->authorize('update', $article);
$article->update($request->all());
}
App\Http\Controllers\Controller 类包含了 Laravel 的 AuthorizesRequests trait。
此 trait 提供了 authorize 方法,它可以被用于快速授权一个指定的行为,当无权限运行该行为时会抛
出 HttpException。 authorize 方法接收两个参数,第一个为授权策略的名称,第二个为进行授权验
证的数据。
14. 创建视图文件
Blade 是Laravel 中提供的一套模板引擎,在 Blade 视图中我们可以使用 Laravel 为这套引擎定义的一些默认方法,并完全兼容 PHP 语法的书写。在项目运行时,Laravel 会把所有的 Blade 视图进行编译缓存成普通的 PHP代码。模板放在resources\views\目录中。
ps:{{}}和{!! !!} :{{}}支持转义,一段html代码只是被当成普通的字符串输出 ,{!! !!} 不支持转义,一段html代码可以被正常的解析
<script>
//sss
var filters = {!! json_encode($filters) !!};
</script>