Laravel框架学习笔记
001需求和安装
需求
PHP >= 7.3
BCMath PHP 拓展
Ctype PHP 拓展
Fileinfo PHP 拓展
JSON PHP 拓展
Mbstring PHP 拓展
OpenSSL PHP 拓展
PDO PHP 拓展
Tokenizer PHP 拓展
XML PHP 拓展
安装
composer create-project --prefer-dist laravel/laravel blog
运行
php artisan serve
注: 需要给storage
文件夹写权限
002文件夹结构的详细
根目录
app 目录
bootstrap 目录
config 目录
database 目录
public 目录
resources 目录
routes 目录
storage 目录
tests 目录
vendor 目录
APP目录
Broadcasting 目录
Console 目录 用于控制台注册
Events 目录
Exceptions 目录 注册处理异常方法
Http 目录
Jobs 目录
Listeners 目录
Mail 目录
Models 目录
Notifications 目录
Policies 目录
Providers 目录
Rules 目录
M:app/Models
V:resource/views
C:app/Controllers
003了解着陆页
// route/web.php
Route::get('/', function () {
return view('welcome');
});
返回resources/views/welcome.blade.php
文件
004创建第一个程序
查看帮助
php artisan
php artisan help 命令
创建控制器
php artisan make:controller Site
// app/Http/Controllers/Site.php
public function first()
{
// echo "<h1>欢迎来到我的第一个控制器</h1>";
return view("first"); // first.blade.php
}
// routes/web.php
/* 如果controller没有任何操作, 可以直接调用view
use App\Http\Controllers\Site;
Route::get("/first", [Site::class, "first"]);
*/
Route::get("/first", function () {
return view("first");
});
// resources/views/first.blade.php
<h1>欢迎来到我的第一个控制器</h1>
005006路由
// routes/web.php
// 基础路由
Route::get("/first", [Site::class, "first"]);
// 视图路由
Route::view("/services", "first");
// 带参路由
Route::get("/services/{id}", [Site::class, "first"]);
Route::get("/services/{id?}", [Site::class, "first"]);
Route::get("/services/{id}/{name}", [Site::class, "first"]);
// 重定向路由
Route::redirect("/here", "/there");
Route::redirect("/here", "/there", 301);
// 正则匹配路由
Route::get("/services/{id}", [Site::class, "first"])
->where("id", "[0-9+]");
Route::get("/services/{id}/{name}", [Site::class, "first"])
->where(["id" => "[0-9]+", "name" => "[a-zA-Z]+"]);
007视图的完整详细信息
// routes/web.php
/*
Route::get("/services/{id}/{name}", function ($id, $name) {
return view("services", ["id"=>$id, "name"=>$name]);
})->where(["id" => "[0-9]+", "name" => "[a-zA-Z]+"]);
*/
Route::get("/services/{id}/{name}", function ($id, $name) {
return view("services", compact("id", "name"));
})->where(["id" => "[0-9]+", "name" => "[a-zA-Z]+"]);
// resources/views/services.blade.php
<h1>这是服务 {{$id}} 名称是{{$name}}</h1>
008009blade模板引擎
// resources/views/services.blade.php
// 模板基本语法
<?php echo $name; ?> ~ {{$name}}
{{-- 注释, 不会解析在html中 --}}
{{ strtoupper("hello") }}
@isset($name)
@endisset
@empty($name)
@endempty
@if (count($arr) > 0)
@elseif(...)
@else
@endif
@for($i = 0; $i<10; $i++)
@endfor
// 文件包含语法
// 新建 resources/views/articles/top_hearder.blade.php
@include("articles.top_hearder")
@csrf
@foreach($arr as $value)
<h4>{{$value}}</h4>
@endforeach
@json($arr) // json_encode($arr)
010创建布局和使用布局
// 新建 resources/views/layouts/app.blade.php
// 在 resources/views/about.blade.php 中 继承布局
@extends("layouts.app") // 继承布局
// @section("content", "我是about的title")
@section("content") // 定义了片段的内容
<div>我是about里的内容</div>
@endsection
// 在 resources/views/layouts/app.blade.php 中 显示片段的内容
@yield("content") // 显示片段的内容
011012组件的创建和使用
创建
php artisan help make:component
php artisan make:component message
会生成2个文件
app/View/Components/Message.php
resources/views/components/message.blade.php
// app/View/Components/Message.php
public $type; // 定义public属性后, 可以在组件里使用属性
public $message;
public function __construct($type, $message)
{
$this->type = $type;
$this->message = $message;
}
public function render()
{
return view('components.message');
}
// resources/views/components/message.blade.php
<div>
<!-- Be present above all else. - Naval Ravikant -->
这是一个组件 内容
类型是: {{$type}}
内容是: {{$message}}
</div>
组件使用
// resources/views/first.blade.php
<x-{{}}/>
<x-message/>
<h3>
<x-message type="success" :message="$message"/>
</h3>
013组件中的插槽和内部插槽
php artisan make:component Alert
插槽
// resources/views/components/alert.blade.php
<div>
{{$solt}}
</div>
// resources/views/first.blade.php
<x-alert> 弹出数据 </x-alert>
内部插槽
// resources/views/components/alert.blade.php
<div>
{{$solt}}
{{$title}} // 使用内部插槽, x-slot的name属性
</div>
// resources/views/first.blade.php
// 内部插槽, 用x-slot的name属性定义
<x-alert> <x-slot name="title">首页</x-slot> 弹出数据 </x-alert>
014内联组件
php artisan make:component MessageBox --inline
配置
// app/View/Components/MessageBox.php
public $name; // 定义public属性后, 可以在组件里使用属性
public function __construct($name)
{
$this->name = $name;
}
public function render()
{
return <<<'blade'
<div>
{{$name}} // 111 // 组件的基本使用
{{$slot}} // 222 // 组件的插槽
{{$my_message}} // 我的信息 // 组件的内部插槽
</div>
blade;
}
使用
// resources/views/first.blade.php
<x-message-box name="111"/> // 组件的基本使用
<x-message-box name="111">222</x-message-box> // 组件的插槽
<x-message-box name="111"> <x-slot name="my_message">我的信息</x-slot> 222</x-message-box> // 组件的内部插槽
015创建并将表单提交至服务器
php artisan make:controller StudentController --resource
php artisan make:request StoreStudentData
路由
// routes/web.php
Route::resource("student", StudentCrontroller::class);
控制器
// app/Http/Controllers/StudnetController.php
public function index()
{
return view("student.index");
}
public function create()
{
return view("student.create");
}
public function store(StoreStudentData $request)
{
$request->validated();
var_dump($request->all());
}
public function show($id)
{
}
public function edit($id)
{
}
public function update(Request $request, $id)
{
}
public function destroy($id)
{
}
列表
// resources/views/student/index.blade.php
<a href="{{route("student.create")}}">添加</a>
新增
// resources/views/student/create.blade.php
<form action="{{route("student.store")}}" method="post">
@csrf
姓名: <input type="text" name="name" value="{{old("name")}}"><br>
@error("name")
{{$message}}<br>
@enderror
邮箱: <input type="text" name="email" value="{{old("email")}}"><br>
@error("email")
{{$message}}<br>
@enderror
手机: <input type="text" name="mobile" value="{{old("mobile")}}"><br>
@error("mobile")
{{$message}}<br>
@enderror
<input type="submit" value="提交"><br>
</form>
016017018019表单数据验证 接015
数据验证
// app/Http/Requests/StoreStudentData.php
public function authorize()
{
return true;
}
public function rules()
{
return [
"name" => "required|min:6",
"email" => "required",
"mobile" => "required",
];
}
public function messages()
{
return [
"name.required" => "Name is needed",
"email.required" => "email is needed",
"mobile.required" => "mobile is needed",
"name.min" => "Name 必须 大于6个字符",
];
}
020数据库连接基础
// .env
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel85
DB_USERNAME=root
DB_PASSWORD=root
// config/database.php
021022运行数据库原始查询
DB::insert()
$users = DB::insert("insert into students (name, age,address) values ('hahaha', 10, 'address')");
// 返回true或false
DB::update()
$users = DB::update("update students set age = '10' where name = ?", ['hahaha']);
// 返回更新行数n
DB::select()
$users = DB::select("select * from students where id = :id", ["id" => 1]);
// 返回二维数组或array{}
DB::delete()
$users = DB::delete("delete from students where `name` = ?", ['hahaha']);
// 返回删除行数n
023迁移和使用方法
php artisan make:migration create_students_table # 创建
php artisan migrate # 迁移
php artisan migrate --seed # 迁移并生成faker数据
php artisan migrate:rollback # 回滚
php artisan migrate:refresh # 迁移 + 回滚
// database/migrations/2021_05_16_***_create_students_table.php
public function up()
{
Schema::create('students', function (Blueprint $table) {
$table->id(); // id
$table->string("name", 120); // string
$table->string("email", 50)->nullable(); // 可以为空
$table->string("mobile", 30)->nullable();
$table->integer("age")->default(0); // 默认值
$table->enum("gender", ["male", "female", "others"]); // 枚举
$table->text("address")->comment("地址"); // comment描述
$table->timestamp("created_at")->useCurrent(); // 当前时间戳
$table->timestamp("updated_at")->useCurrent();
});
}
024迁移和列修饰符将列添加到表
https://learnku.com/docs/laravel/8.x/migrations/9403
025Seeder基础知识
php artisan make:seeder StudentSeeder # 生成学生seeder
php artisan db:seed # 执行 database/seeders/DatabaseSeeder.php
php artisan db:seed --class=StudentSeeder # 执行指定seeder
// database/seeders/StudentSeeder.php
public function run()
{
// 生成一条数据
DB::table("students")->insert([
"name" => "小白",
"email" => "[email protected]",
"mobile" => "1624645324254",
"age" => 56,
"gender" => "male",
"address" => "上海市嘉定区江桥"
]);
// faker 生成伪造数据 一条
$faker = \Faker\Factory::create();
DB::table("students")->insert([
"name" => $faker->name,
"email" => $faker->safeEmail,
"mobile" => $faker->phoneNumber,
"age" => $faker->numberBetween(20, 40),
"gender" => $faker->randomElement(['male','female','others']),
"address" => $faker->address
]);
}
注: 修改faker
语言, config/app.php
文件'faker_locale' => 'zh_CN',
// database/seeders/DatabaseSeeder.php
public function run()
{
// \App\Models\User::factory(10)->create();
// $this->call(
// StudentsSeeder::class
// );
\App\Models\Student::factory(10)->create();
}
026faker库的使用
laravel自带此库
https://github.com/fzaninotto/Faker
027工厂基础和seeder使用工厂
php artisan make:model Student # 建model, 工厂依赖model
php artisan make:factory StudentFactory # 建工厂
// database/factories/StudentFactory.php
public function definition()
{
return [
"name" => $this->faker->name,
"email" => $this->faker->safeEmail,
'mobile' => $this->faker->phoneNumber,
"age" => $this->faker->numberBetween(20, 40),
"gender" => $this->faker->randomElement([
"male",
"female",
"others"
]),
"address" => $this->faker->address
];
}
028模型基础及成员变量的使用
https://learnku.com/docs/laravel/8.x/eloquent/9406
php artisan make:mode Employee --all
# Model created successfully.
# Factory created successfully.
# Created Migration: 2021_05_20_010345_create_employees_table
# Seeder created successfully.
# Controller created successfully.
// app/Models/Employee.php
class Employee extends Model
{
use HasFactory;
protected $table = "tpl_employee"; // 定义表名 默认employee
protected $primaryKey = "student_id"; // 定义主键 默认id
protected $keyType = "string"; // 主键不是整数
public $incrementing = false; // 主键不自增
public const CREATED_AT = "create_date";
public const UPDATED_AT = "last_update";
public $timestamps = false; // 不存时间戳, miration建表语句中也要去掉timestamp
}
029创建表单数据并保存到数据表里
https://www.youtube.com/watch?v=0m5h45_bQgE&list=PLT9miexWCpPUCBjFVFR_05Rr8pvLeoHO0&index=29
php artisan serve
php artisan migrate
php artisan make:model Student -a
# Generate a migration, seeder, factory, and resource controller for the model
030会话Flash消息的设置和表单重定向
https://www.youtube.com/watch?v=//QNvUKf9pouc&list=PLT9miexWCpPUCBjFVFR_05Rr8pvLeoHO0&index=30
// 表单提交后, flash消息回显
// session()->flash("key", "message");
$request->seession()->flash("success", "添加成功");
return redirect(route("users/create"));
@if(session()->has("success"))
<h3>{{session("success")}}</h3>
@endif
031数据库模型从表中查数据
Student::all();Student::get();
Student::where()->first(); // 查一条
Student::find(1); // 查一条
Student::find([1,5,8]); // 查多条
Student::firstWhere('email', ''); // 查一条
032数据库到布局/model
到布局
https://www.youtube.com/watch?v=gDvxJLmsxZw&list=PLT9miexWCpPUCBjFVFR_05Rr8pvLeoHO0&index=32
033删除操作
https://www.youtube.com/watch?v=gDvxJLmsxZw&list=PLT9miexWCpPUCBjFVFR_05Rr8pvLeoHO0&index=33
$student = Student::find($id);
$student->delete();
034更新操作
https://www.youtube.com/watch?v=NzM1MiguPiA&list=PLT9miexWCpPUCBjFVFR_05Rr8pvLeoHO0&index=34
035查询生成器 select
DB::table('students')->get();
DB::table('students')->select("name", "email as email_address")->get();
DB::table('students')->where('id', 5)->select()->get();
036选择查询 and or
$students = DB::table('students')->where('id', 3)->where('name', 'abc')->get();
$students = DB::table('students')->where('id', 3)->where(function($query){
$query->where('name', 'abc')->orWhere('email', '[email protected]');
})->get();
$students = DB::table('students')->where('name', 'abc')->orWhere(function($query){
$query->where('id', 3)->where('email', '[email protected]');
})->get();
$students = DB::table('students')->whereBetween('id', [2,30])->get();
$students = DB::table('students')->whereIn('id', [2,30])->get();
037连接查询 join left right
$students = DB::table('students')->join('courses','students.id','=','courses.student_id')->get();
$students = DB::table('students')-select('')>join('courses','students.id','=','courses.student_id')->get();
038插入和更新
DB::table('students')->insert([
'name'=>'test',
'age'=>20
]);
$insert_id = DB::table('students')->insertGetId([
'name'=>'test',
'age'=>20
]);
DB::table('students')->insert([
[
['name'=>'test2','age'=>20],
['name'=>'test3','age'=>22],
]
]);
DB::table('students')->where('id', 5)->update([
'name'=>'test','age'=>99
]);
039更新 删除和截断
DB::table('students')->updateOrInsert(
['name'=>'test'], //条件
['name'=>'hahaha', 'age'=>55] // data
);
DB::table('students')->where('name','test')->delete();
DB::table('students')->truncate();
040中间件基础关于全局中间件
php artisan make:middleware CountryCheck
// app/Http/Kernel.php $middleware
\App\Http\Middleware\CountryCheck::class,
// app/Http/Middleware/CountryCheck.php
if ($request->country && !in_array($request->country, ['us', 'in'])) {
return redirect('noaccess');
}
041中间件组
// app/Http/Kernel.php $middlewareGroups
'apprestrict' =>[
\App\Http\Middleware\CountryCheck::class,
],
// routes/web.php
Route::get("/sample1", function () {
echo "sample 1 page";
});
Route::get("/sample2", function () {
echo "sample 2 page";
});
Route::group(['middleware' =>['apprestrict']], function ()
{
Route::get("/sample3", function () {
echo "sample 3 page";
});
Route::get("/sample4", function () {
echo "sample 4 page";
});
});
042路由中间件
// app/Http/Kernel.php $routeMiddleware
'ck' => \App\Http\Middleware\CountryCheck::class,
// routes/web.php
Route::get("/sample5", function () {
echo "sample 5 page";
})->middleware('ck');
043使用GET REST APIs
php artisan make:countroller PostController
// app/Http/Controllers/PostController.php
public function index()
{
$posts = Http::get("http://jsonplaceholder.typicode.com/posts");
return json_decode($posts);
}
044本地化 多语言网站概念
https://www.youtube.com/watch?v=vn-OTkiYJLI&list=PLT9miexWCpPUCBjFVFR_05Rr8pvLeoHO0&index=44
php artisan make:controller ServiceController
// app/Http/Controllers/ServiceController.php
public function service($locale)
{
App::setLocale($locale);
return view("lang");
}
// resources/views/lang.blade.php
<h3>{{ __('app.langtest') }}</h3>
<h3>{{ trans('app.langtest') }}</h3>
<h3>@lang('app.langtest')</h3>
// resources/lang/en/app.php
// resources/lang/zh_CN/app.php
return [
"langtest" => "欢迎来到实力至上主义的教室",
];
045访问器的概念
// app/Models/Student.php
public function getEmailAttribute($value){
return strtoupper($value);
}
public function getCreatedAtAttribute($value)
{
return date("Y-m-d H:i:s", strtotime($value));
}
// app/Http/Controllers/StudentController.php
public function index()
{
$students = Student::all();
return $students;
}
046修改器的概念
// app/Models/Student.php
public function setMobileAttribute($value)
{
$this->attributes["mobile"] = "+91" . $value;
}
047ORM一对一的关系
// app/Models/User.php
public function phone()
{
return $this->hasOne(Phone::class, 'user_id', 'id'); // 关联的model/phone, 关联的model字段/phone.user_id, 当前的model字段/user.id
}
// app/Models/Phone.php
public function user()
{
return $this->belongsTo(User::class, 'user_id', 'id'); // 反向关联的model/user, 当前model关联user/id, 反向关联model的phone/user_id
}
048一对多
// app/Models/User.php
public function phones()
{
return $this->hasMany(Phone::class); // 第二个第三个参数会自动识别 user_id, id
}
049一对一直通关系
// Person -> Broker -> Home
public function homeInformation()
{
return $this->hasOneThrough(Home::class, Broker::class);
}
050一对多直通关系
// Person -> Broker -> Homes
public function homeList()
{
return $this->hasManyThrough(Home::class, Broker::class);
}
051多对多
// app/Models/User.php
public function roles()
{
return $this->belangsToMany(Role::class);
}
// app/Models/Role.php
public function getUsers()
{
return $this->belangsToMany(User::class);
}
052如何使用列名
看047
053身份验证基本描述
composer require laravel/breeze --dev
php artisan help breeze:install
npm install && npm run dev
054脚手架文件/功能
055JetStream
composer require laravel/jetstream
php artisan jetstream:install livewire
php artisan migrate
npm install && npm run dev
056关于脚手架文件 Auth的JetStream
// config/fortify.php
'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' => true]),
Features::accountDeletion(), // 删除用户
],
057脚手架文件和身份验证
composer require laravel/jetstream
php artisan jetstream:install inertia
php artisan migrate
npm install && npm run dev
058什么是stub, 存根定制
php artisan make:controller EmployeeController
php artisan make:model Employee
php artisan stub:publish
/stubs 目录
059路由模型绑定
060URL生成器功能
url()
route()
action()
061关于资源控制器
php artisan make:controller MemberController -r
php artisan route:list
062063CURD
php artisan make:model Device -m # 创建模型和迁移文件
# php artisan make:model Device -a # 创建所有
php artisan migrate # 迁移
php artisan make:controller DeviceController -r --model=Device # 创建控制器use Device model
064布局
071thinker简介
php artisan thinker
echo "11";
Student::insert(["name"=>"hahaha",'created_at'=>new DateTime()]);
Student::create(["name"=>"hahaha",'created_at'=>new DateTime()]);
Student::all();
Student::find(1);
Student::where('name'=>'hahaha')->get();
Student::where('name'=>'hahaha')->first();
Student::where('name'=>'hahaha')->update(['name'=>'222']);
Student::where('id'=>2)->delete();
072thinker使用DB类
DB::table('students')->insert([ 'name'=>'lisi','created_at'=>new DateTime() ]);
DB::table('students')->get();
where, first, update, delete
073关于model事件-1
Create,update,delete,save: creating() & created() # 前 后
// app/Models/Device.php
public static function boot(){
parent::boot();
static::creating(function($item){
Log::info( "访问前" . $item );
});
}
074075Events Listener监听器-23
php artisan make:event StudentCreatingEvent
// app/Models/Device.php
protected $dispatchesEvents = [
'creating' => StudentCreatingEvent::class,
];
php artisan make:listener StudentCreatingListener --event=StudentCreatingEvent
076Observer(观察者)模型事件-4
php artisan make:observer StudentObserver --model=Student
077自定义HTTP 404页面
php artisan vendor:publish --tag=laravel-errors
081创建自定义artisan命令
php artisan make:command UserInfo
// app/Console/Commands/UserInfo.php
protected $signature = 'user:info';
protected $description = '查询用户信息';
public function handle()
{
$name = $this->ask("你的名字?");
// $this->info('输入成功!' . $name);
// $this->line('输入成功!' . $name);
$this->error('输入成功!' . $name);
return 0;
}
082自定义命令和model交互
https://www.youtube.com/watch?v=XMUArtkDy0A&list=PLT9miexWCpPUCBjFVFR_05Rr8pvLeoHO0&index=82
083使用Gmail SMTP发邮件
php artisan make:controller SampleController
php artisan make:mail TestMail
084markdown发送邮件
php artisan make:mail TestMail2 --markdown=emails.sample-mail2
086markdown自定义样式
php artisan vendor:publish --tag=laravel-mail
087多数据库链接
public $connection = "mysql_2"; # model
DB::connection("mysql_2")->table('procuts')->get(); // controller
Schena::connection('mysql_2')->create() // migration
088Helpers使用
// app/Helpers.php
// composer.json
"autoload"
"files": [
"app/Helpers.php"
]
composer dump-autoload
089路由前缀
Route::prefix('admin')->group(function(){
});
091分页
https://www.youtube.com/watch?v=CaHF1zbevwg&list=PLT9miexWCpPUCBjFVFR_05Rr8pvLeoHO0&index=91
https://onlinewebtutorblog.com/step-by-step-laravel-8-pagination-tutorial/
092trait的概念
https://onlinewebtutorblog.com/concept-of-trait-in-laravel-8-tutorial-with-example/
093多重身份验证和角色登录访问
https://www.youtube.com/watch?v=A0M4qn5L03I&list=PLT9miexWCpPUCBjFVFR_05Rr8pvLeoHO0&index=93