网站设计
约 3470 字大约 12 分钟
2026-07-06
概念
回调函数
回调函数的作用是将一个函数作为参数传递给另一个函数, 当这个函数执行完毕后, 会调用这个回调函数, 并将结果传递给回调函数
function myFunction(param1, param2, callback) {
const result = param1 + param2
callback(result)
}
myFunction(1, 2, (result) => {
console.log(`回调函数被调用,结果为:${result}`)
})类中的静态方法
如果想要调用一个类中的函数,需要先将类实例化才能够调用类中的函数
class MyClass {
public function myMethod() {
return "这是一个普通方法";
}
}
$myObject = new MyClass();
echo $myObject->myMethod(); // 输出: 这是一个普通方法如果想要直接调用类中的函数而不需要实例化这个类,那么就需要将这个函数定义为静态方法
class MyClass {
public static function myStaticMethod() {
return "这是一个静态方法";
}
}
echo MyClass::myStaticMethod(); // 输出: 这是一个静态方法laravel
路由
提示
在 laravel11 之后的版本需要执行命令
php artisan install:api才能在在 /routes/api.php 中定义接口, 否则会没有这个文件
常用路由
Route::get($uri, $callback);
Route::post($uri, $callback);
Route::put($uri, $callback);
Route::patch($uri, $callback);
Route::delete($uri, $callback);
Route::options($uri, $callback);一般直接绑定控制器即可,不需要使用回调函数
Route::get('/', [UserController::class, 'show']);特殊路由
Route::match(['get', 'post'], '/', function () {
// ...
});
Route::any('/', function () {
// ...
});
// 第三个参数可以设置状态码,默认是 302
Route::redirect('/here', '/there', 301);
// 第三个参数是传给视图的参数
Route::view('/welcome', 'welcome', ['name' => 'Taylor']);提示
路由的定义也有顺序关系
比如我们需要在 / 下定义一个 any 路由和一个 post 路由
如果你先定义了 any 路由,那么所有的请求都会被 any 路由匹配到,post 路由将永远不会被匹配到。
路由参数
Route::get('user/{id}', function ($id) {
return 'User '.$id;
});在控制器里也是一样的
Route::get('user/{id}', [UserController::class, 'show']);class UserController extends Controller
{
public function show(Request $request, $id)
{
return 'User '.$id;
}
}路由参数的值有时候是可选的, 在参数的结尾加上 ? 就可以了, 但是在后面的处理函数里要给参数一个默认值
Route::get('user/{name?}', function ($name = null) {
return $name;
});分组
分组一般配合 prefix、middleware 等使用
prefix 是路由前缀,比如原本的路由是 /users,加上 prefix('admin') 后就变成了 /admin/users
middleware 是中间件,所有的路由都会经过中间件的处理
Route::prefix('admin')->group(function () {
Route::get('users', function () {});
});
// 此处也可以直接导入中间件的类
Route::middleware(['first', 'second'])->group(function () {
Route::get('/', function () {});
});中间件
提示
创建中间件请使用 php artisan make:middleware 命令
一般在路由中使用中间件需要先在 /bootstrap/app.php 中注册
然后再到你的路由中去使用
<?php
namespace App\Http\Middleware;
use App\Http\Controllers\ResponseController;
use App\Models\User;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Symfony\Component\HttpFoundation\Response;
class Auth2
{
/**
* Handle an incoming request.
*
* @param Closure(Request): (Response) $next
*/
// 请求参数 是否继续参数 中间件参数,他是从路由中传递过来的
public function handle(Request $request, Closure $next, $type="ADMIN|WORKER|USER", $statusCode=422): Response
{
//校验是否携带token字段
$validated=Validator::make($request->query(),[
'token'=>'required'
]);
if($validated->fails()){
return ResponseController::failure($statusCode);
}
//判断用户角色
$type=explode('|',$type); //把$type按|拆成数组
$user=User::query()->firstWhere('token',$request['token']);
if(!$user){
return ResponseController::failure(404,'not found');
}
if(!in_array($user['type'],$type)){
return ResponseController::failure(401,'unauthorized access');
}
// 如果不调用这个 $next($request) 函数,那么这个中间件就不会继续执行下去,也就不会进入到路由中定义的回调函数中
return $next($request);
}
}use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Exceptions;
use Illuminate\Foundation\Configuration\Middleware;
return Application::configure(basePath: dirname(__DIR__))
->withRouting(
web: __DIR__.'/../routes/web.php',
api: __DIR__.'/../routes/api.php',
commands: __DIR__.'/../routes/console.php',
health: '/up',
)
->withMiddleware(function (Middleware $middleware): void {
// 在此处调用 alias 方法注册中间件别名
$middleware->alias([
'auth2' => \App\Http\Middleware\Auth2::class,
]);
})
->withExceptions(function (Exceptions $exceptions): void {
//
})->create();// ↓这里就是你前面注册的alias别名
Route::middleware(['auth2:ADMIN,422'])->group(function () {
Route::get('/', function () {});
});迁移
创建迁移
这里的 create_xxxx_table 是固定的格式,中间的 xxxx 是你要创建的表名,必须是复数形式。
php artisan migrate:make create_users_table运行迁移
php artisan migrate如果迁移存在破坏性
php artisan migrate --force如果想要完全重新执行一次迁移,这会删除现在的所有表,然后重新开始执行迁移
php artisan migrate:refresh --force如果迁移还需要同步执行 seeder ,那么需要带上 --seed 参数
php artisan migrate:refresh --seed --forceseeder
seeder 是用来给数据库表插入测试数据的,但是我们也可以用来创建默认数据使用
默认的 seeder 文件在 /database/seeders/DatabaseSeeder.php
<?php
namespace Database\Seeders;
use App\Models\Table;
use App\Models\User;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
use WithoutModelEvents;
/**
* Seed the application's database.
*/
public function run(): void
{
User::query()->create([
"username" => "admin",
"password" => md5("adminpass"),
'type' => 'ADMIN',
'token' => ''
]);
User::query()->create([
"username" => "user",
"password" => md5("userpass"),
'type' => 'USER',
'token' => ''
]);
User::query()->create([
"username" => "worker",
"password" => md5("workerpass"),
'type' => 'WORKER',
'token' => ''
]);
for ($i = 1; $i <= 3; $i++) {
Table::query()->create([
"table_type" => "A",
"status" => "UNOCCUPIED"
]);
}
for ($i = 1; $i <= 3; $i++) {
Table::query()->create([
"table_type" => "B",
"status" => "UNOCCUPIED"
]);
}
for ($i = 1; $i <= 3; $i++) {
Table::query()->create([
"table_type" => "C",
"status" => "UNOCCUPIED"
]);
}
}
}CSRF
你只需要记住,这个东西只有在你把接口定义在了 /routes/web.php 里才会生效,如果你把接口定义在了 /routes/api.php 里,那么 CSRF 就不会生效。
然后一般是这样用的, 在 blade 模板里使用 @csrf 指令就可以了,不然的话你会收到一个 419 的错误,表示 CSRF 验证失败。
<form method="POST" action="/profile">
@csrf
...
</form>blade模板
插值语法
中间的 $name 是一个变量, 如果你需要输出一个在变量中的 HTML 代码, 那么你需要使用 {!! $name !!} 来输出, 否则的话会被转义成普通文本
{{ $name }}
{!! $name !!}控制语法
@if(condition)
// 条件为 true 时执行的代码
@elseif(condition)
// 条件为 true 时执行的代码
@else
// 条件为 false 时执行的代码
@endif循环语法
@foreach($users as $user)
// 循环体
@endforeach
@for ($i = 0; $i < 10; $i++)
// 循环体
@endfor
@while (condition)
// 循环体
// 正常的continue和break语法也是在所有循环中可用的
@continue
@break
@endwhile样式语法
@php
$isActive = false;
$hasError = true;
@endphp
// 这里表示如果 $isActive 为 true,则添加 font-bold 类,否则添加 text-gray-500 类
// 如果 $hasError 为 true,则添加 bg-red 类
<span @class([
'p-4',
'font-bold' => $isActive,
'text-gray-500' => ! $isActive,
'bg-red' => $hasError,
])></span>
<span class="p-4 text-gray-500 bg-red"></span>
// 这里表示如果 $isActive 为 true,则添加 font-weight: bold 样式,否则不添加
<span @style([
'background-color: red',
'font-weight: bold' => $isActive,
])></span>标签语法
常用的一些 html 属性也有对应的命令, 可以省去一些自己去写 if 的麻烦, 例如 checked、selected、disabled、readonly、required
<input
type="checkbox"
name="active"
value="active"
@checked(true)
/>
<select name="version">
<option value="aa" @selected(false)>
aaa
</option>
</select>
<button type="submit" @disabled(true)>Submit</button>
<input
type="email"
name="email"
value="email@laravel.com"
@readonly(false)
/>
<input
type="text"
name="title"
value="title"
@required(true)
/>控制器
php artisan make:controller在类中新建函数, 函数必须使用 public 修饰符
过滤器
所有可用规则: https://www.laravel.wiki/validation#%E5%8F%AF%E7%94%A8%E9%AA%8C%E8%AF%81%E8%A7%84%E5%88%99
$validator = Validator::make($request->post(), [
"name" => "required|string|max:255",
"email" => "required|email|unique:users",
"password" => "required|string|min:6|confirmed",
// confirmed规则默认会去验证password_confirmation字段, 如果你想要验证其他字段, 那么就需要使用same规则来验证
// password也就是当前字段的名称, 比如密码字段叫aaa, 那么验证的字段就是 aaa_confirmation
// "password_confirmation" => "required|string|same:password"
]);
// 不过这里的一些过滤规则只能和laravel自带的blade配合使用,我们可以让他更加通用一些
if ($validator->fails()) {}class ExampleController extends Controller
{
public function register(Request $request)
{
$validator = Validator::make($request->post(), [
"name" => "required|string|max:255",
"email" => "required|email|unique:users",
"password" => "required|string|min:6|confirmed",
// confirmed规则默认会去验证password_confirmation字段, 如果你想要验证其他字段, 那么就需要使用same规则来验证
// password也就是当前字段的名称, 比如密码字段叫aaa, 那么验证的字段就是 aaa_confirmation
// "password_confirmation" => "required|string|same:password"
]);
// 不过这里的一些过滤规则只能和laravel自带的blade配合使用,我们可以让他更加通用一些
if ($validator->fails()) {
// 判断哪个规则被触发了
$failed = $validator->failed();
// 判断是不是email的unique规则被触发了
// 这里的 Unique 是规则的名称, 不是字段的名称
// 并且首字母需要大写, 比如 min:6 规则触发了, 那么这里就是 $failed["password"]["Min"] 这个属性存在, 也就是 Min 首字母大写
if (isset($failed["email"]["Unique"])) {
return response()->json([
"success" => false,
"message" => "邮箱已经被注册了"
],422);
}
return response()->json([
"success" => false,
"message" => "参数验证失败"
], 422);
}
// 如果验证通过, 那么就可以进行注册了
}
}集合
所有可用方法: https://www.laravel.wiki/collections#%E5%8F%AF%E7%94%A8%E6%96%B9%E6%B3%95
$collection = collect([1, 2, 3]);
$collection->all(); // [1, 2, 3]
$collection->avg(); // 2
$collection->chunk(2); // [[1, 2], [3]]
$collection->map(function ($item, $key) {
return $item * 2;
}); // [2, 4, 6]
$collection->filter(function ($item, $key) {
return $item > 2;
}); // [3]辅助函数
最常用的就是调试命令
dd($var); // 打印变量并终止程序
dump($var); // 打印变量但不终止程序可用辅助函数: https://www.laravel.wiki/helpers#%E5%85%B6%E4%BB%96
只要看这个其他就够了
模型
php artisan make:model在 model 中有几个常用属性
class User extends Model
{
// 在插入用户的时候需要将插入的字段添加到这个属性中
// 比如我们在调用 create 函数的时候, 传入的字段如果不在这个 $fillable 中, 那么他就不会被添加到操作数据库的sql语句中
protected $fillable = [
"name",
"email",
"password",
"token"
];
// 这里定义的属性会在序列化的时候去除
// 比如我们通过 get 函数获取到了这个User模型, 我们直接把他放到 response->json($user) 中, 那么返回的json中就不会有token和password字段了
protected $hidden = [
"token",
"password"
];
// 关闭在调用 create 函数的时候添加的 created_at 和 updated_at 字段, 也就是关闭时间戳
public $timestamps = false;
}在控制器或其他部分使用模型
在调用模型之前需要先调用 query 函数后,才能够获得正常的提词器。 还有一些常用的附属函数:https://www.laravel.wiki/eloquent
User::query()->create([
"name" => $request->post("name"),
"email" => $request->post("email"),
"password" => Hash::make($request->post("password")),
"token" => Str::uuid()->toString()
]);获取所有数据
$users = User::query()->get();查询条件
// 查询年龄大于18岁的用户
$users = User::query()->where('age', '>', 18)->get();
// 查询年龄大于18岁且名字是John的用户
$users = User::query()->where('age', '>', 18)->where('name', '=', 'John')->get();
// 简化写法
$users = User::query()->where([
"age" => 18,
"name" => "John"
])->get();
// 也支持高级数组写法
$users = User::query()->where([
["age", ">", 18],
["name", "=", "John"]
])->get();
// 查询年龄大于18岁或名字包含John的用户
$users = User::query()->where('age', '>', 18)->orWhere('name', 'like', '%John%')->get();
// 查询id在1,2,3之间的用户
$users = User::query()->whereIn('id', [1, 2, 3])->get();获取条目数量
$count = User::query()->where('age', '>', 18)->count();更新数据
User::query()->where('id', 1)->update(['name' => 'New Name']);删除数据
User::query()->where('id', 1)->delete();新建数据
User::query()->create([
'name' => 'John Doe',
'email' => 'john.doe@example.com',
'password' => bcrypt('password'),
]);高级用法
Str类
// 生成一个uuid, 并把他转换成字符串类型
$token = Str::uuid()->toString();关于导入
一般导入的辅助类 Validator Request Str Random 等等
都优先使用 Illuminate\Support\Facades 下的
如果没有就使用 Illuminate\Support 下的
关于路由
提示
此处的路由指的是 web.php 中的路由, 不是 api.php 中的路由
在 laravel 中的路由分为两种,一种是我们在 /routes 中定义的路由,另一种就是我们在 /public 下放置的静态资源文件
在 /routes 中定义的路由一般表示需要经过 laravel 的处理,才能够返回给前端的路由
在 /public 下放置的静态资源文件一般表示不需要经过 laravel 的处理,直接返回给前端的路由
在什么情况下需要经过 laravel 的处理呢?
比如你使用了 blade 模板引擎(就是放置在 /resources/views 下的模板文件,我们称为 blade 模板),那么你在 /routes 中定义的路由就需要经过 laravel 的处理,才能够返回给前端
一般情况下,如果你的项目是一个前后端分离的项目,那么你就不会去使用 blade 模板引擎,也就直接放置在 /public 下的静态资源文件就可以了,不需要经过 laravel 的处理
js
网络请求
使用 fetch 函数
在使用 fetch 与 laravel 后端进行网络请求的时候需要手动携带上 头部信息
await fetch('/api', {
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
})如果 fetch 函数在里另一个函数里, 那么这个函数需要加上 async 修饰符, 并且在调用这个函数的时候需要加上 await 修饰符
比如:
async function getData() {
await fetch('/api', {
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
})
}
button.addEventListener('click', async () => {
await getData()
})路由参数解析
对于路由参数的提取通常会比较麻烦, 我们可以使用 URLSearchParams 来解析路由参数, 这个类可以将路由参数解析成一个对象, 然后我们就可以通过对象的属性来获取路由参数的值
const urlParams = new URLSearchParams(window.location.search)
const id = urlParams.get('id')