composer create-project --prefer-dist laravel/laravel larabbs "8.*"
php artisan --version
location / {
try_files $uri $uri/ /index.php?$query_string;
}
composer require nwidart/laravel-modules
php artisan vendor:publish --provider="Nwidart\Modules\LaravelModulesServiceProvider"
php artisan module:make Admin
4.要让模块目录中定义的类可以自动加载,需要配置根目录下的composer.json
{
"autoload": {
"psr-4": {
"App\\": "app/",
"Modules\\": "Modules/"
}
}
}
composer dump-autoload
定义在 routes/api.php 文件中的路由,将自动应用 /api URI 前缀,可以通过修改 RouteServiceProvider 类来修改前缀和其他路由组选项。
Route::get('/greeting', function () {
return 'Hello World';
});
//http://laram.com/api/v1/admin/user
Route::group(['prefix' => 'v1/admin','middleware'=>'admin_api_auth'],function () {
//路径用“\”分割
Route::post('/user', "v1\IndexController@test");
});
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::match(['get', 'post'], '/', function () {
//
});
Route::any('/', function () {
//
});
Route::get('/user/{id}', function ($id) {
return 'User '.$id;
});
//在路由中定义多个参数
Route::get('/posts/{post}/comments/{comment}', function ($postId, $commentId) {
//
});
Route::get('/user/{name?}', function ($name = null) {
return $name;
});
Route::get('/user/{name?}', function ($name = 'John') {
return $name;
});
Route::get('/user/{name}', function ($name) {
//
})->where('name', '[A-Za-z]+');
Route::get('/user/{id}/{name}', function ($id, $name) {
//
})->where(['id' => '[0-9]+', 'name' => '[a-z]+']);
//正则表达式模式具
Route::get('/user/{id}/{name}', function ($id, $name) {
//
})->whereNumber('id')->whereAlpha('name');
Route::get('/user/{name}', function ($name) {
//
})->whereAlphaNumeric('name');
Route::get('/user/{id}', function ($id) {
//
})->whereUuid('id');
Route::get('/category/{category}', function ($category) {
//
})->whereIn('category', ['movie', 'song', 'painting']);
// App\Providers\RouteServiceProvider 类的 boot 方法
public function boot()
{
Route::pattern('id', '[0-9]+');
}
Route::get('/user/profile', function () {
//
})->name('profile');
路由名称应始终是唯一的
Route::middleware(['first', 'second'])->group(function () {
Route::get('/', function () {
// 使用第一个和第二个中间件...
});
Route::get('/user/profile', function () {
// 使用第一个和第二个中间件...
});
});
use App\Http\Controllers\OrderController;
Route::controller(OrderController::class)->group(function () {
Route::get('/orders/{id}', 'show');
Route::post('/orders', 'store');
});
Route::domain('{account}.example.com')->group(function () {
Route::get('user/{id}', function ($account, $id) {
//
});
});
Route::prefix('admin')->group(function () {
Route::get('/users', function () {
// Matches The "/admin/users" URL
});
});
1.创建中间件
php artisan make:middleware EnsureTokenIsValid
将在app/Http/Middleware 目录中放置一个新的 EnsureTokenIsValid 类。HTTP 请求在到达应用程序之前必须通过这个中间件
以下中间件将在应用程序处理请求之前**执行一些任务:
<?php
namespace App\Http\Middleware;
use Closure;
class EnsureTokenIsValid
{
public function handle($request, Closure $next)
{
// 执行操作
return $next($request);
}
}
此中间件将在请求由应用程序处理后执行其任务:
<?php
namespace App\Http\Middleware;
use Closure;
class AfterMiddleware
{
public function handle($request, Closure $next)
{
$response = $next($request);
// 执行操作
return $response;
}
}
'admin_api_auth' => \Modules\Admin\Http\Middleware\AdminApiAuth::class,
Route::get('/profile', function () {
//
})->middleware('admin_api_auth');
Route::middleware('admin')->prefix('v1/admin')->group(function () {
Route::post('/user', "v1\IndexController@test");
});
//排除中间件
Route::withoutMiddleware([EnsureTokenIsValid::class])->group(function () {
Route::get('/profile', function () {
//
});
});
//构造函数注入
<?php
namespace App\Http\Controllers;
use App\Repositories\UserRepository;
class UserController extends Controller
{
/**
* 用户存储库实例。
*/
protected $users;
/**
* 创建一个新的控制器实例。
*
* @param \App\Repositories\UserRepository $users
* @return void
*/
public function __construct(UserRepository $users)
{
$this->users = $users;
}
}
//方法注入
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class UserController extends Controller
{
/**
* 存储一个新用户。
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
{
$name = $request->name;
//
}
}
//检索请求路径 : http://larabbs/api/v1/admin/user
$request->path(): //api/v1/admin/user
//检查请求路径 / 路由
$request->is('api/v1/admin/*'):
$request->routeIs('admin.*'):
//检索请求 URL(完整 URL)
$request->url(): //http://larabbs/api/v1/admin/user
$request->fullUrl():
$request->fullUrlWithQuery(['type' => 'phone']);
//检索请求主机
$request->host();
$request->httpHost();
$request->schemeAndHttpHost();
//检索请求方法
$request->method();
$request->isMethod('post');
//请求头
$request->header('X-Header-Name')
$request->header('X-Header-Name', 'default');
$request->hasHeader('X-Header-Name');
//请求 IP 地址
$request->ip();
//请求协商
$request->getAcceptableContentTypes();
//接受内容类型的数组
$request->accepts(['text/html', 'application/json'])
//检索所有输入数据
$request->all();
$request->collect();
//检索一个输入值
$request->input('name');
$request->input('name', 'Sally');
$request->input('products.0.name');
$request->input('products.*.name');
$request->input();
//从查询字符串中检索输入
$request->query('name');
//检索输入数据的一部分
$request->only(['username', 'password']);
$request->only('username', 'password');
$request->except(['credit_card']);
$request->except('credit_card');
//判断输入值是否存在
$request->has('name')
$request->has(['name', 'email'])
//存在,并且不为空
$request->filled('name')
//合并附加输入
$request->merge(['votes' => 0]);
//请求的输入数据中不存在相应的键
$request->mergeIfMissing(['votes' => 0]);
$request->flash();
$request->flashOnly(['username', 'email']);
$request->flashExcept('password');
//old 方法会从 Session 取出之前被闪存的输入数据
$request->old('username');
$file = $request->file('photo');
$file = $request->photo;
$request->hasFile('photo')
//验证成功上传
$request->file('photo')->isValid()
//文件路径和扩展名
$path = $request->photo->path();
$extension = $request->photo->extension();
$path = $request->photo->store('images');
$path = $request->photo->store('images', 's3');
//接受路径、文件名和磁盘名作为其参数
$path = $request->photo->storeAs('images', 'filename.jpg');
$path = $request->photo->storeAs('images', 'filename.jpg', 's3');
return response()->json($result,400);
return response()->download($pathToFile);
return response()->download($pathToFile, $name, $headers);
return response()->file($pathToFile);
return response()->file($pathToFile, $headers);
php artisan modul:make-request TestRequest Admin
<?php
namespace Modules\Admin\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class TestRequest extends FormRequest
{
public function rules()
{
return [
'id'=>'required|is_positive_integer',
];
}
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
public function messages()
{
return ['id.required'=>'id必填','id.is_positive_integer'=>'id需为整数'];
}
}
use Validator;
public function boot()
{
parent::boot();
//验证正整数
Validator::extend('is_positive_integer', function($attribute, $value, $parameters, $validator) {
if (is_numeric($value) && is_int($value + 0) && ($value + 0) > 0) {
return true;
}else{
return false;
}
});
}
public function render($request, Throwable $exception)
{
if($request->is("api/*")){
// api接口主动抛出的异常
if($exception instanceof ValidationException){
$result = [
"code"=>404,
"message"=>array_values($exception->errors())[0][0],
];
return response()->json($result,400);
}
else{
$result = [
"code"=>400,
"message"=>$exception->getMessage(),
];
return response()->json($result,400);
}
}
return parent::render($request, $exception);
}
}