Laravel+API 接口

Laravel+API 接口

网课连接:BIlibili.

中文文档.

1.RestFul Api编码风格

一、API设计

  1. 修改hosts,C:\Windows\System32\drivers\etc\hosts,增加127.0.0.1 api.lv8.com # Laravel 框架 用这个域名来测试(推荐规范)

  2. 在命令行中使用 php artisan serve --host api.lv8.com

  3. .envconfig/database.php中配置mysql数据库等服务用的wamp;

    注意这里的 database.php需要配置 prefix属性

    php 复制代码
            'mysql' => [
                'driver' => 'mysql',
                'url' => env('DATABASE_URL'),
                'host' => env('DB_HOST', '127.0.0.1'),
                'port' => env('DB_PORT', '3306'),
                'database' => env('DB_DATABASE', 'forge'),
                'username' => env('DB_USERNAME', 'forge'),
                'password' => env('DB_PASSWORD', ''),
                'unix_socket' => env('DB_SOCKET', ''),
                'charset' => 'utf8mb4',
                'collation' => 'utf8mb4_unicode_ci',
                'prefix' => 'laravel_',  # 重点
                'prefix_indexes' => true,
                'strict' => true,
                'engine' => null,
                'options' => extension_loaded('pdo_mysql') ? array_filter([
                    PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
                ]) : [],
            ],
  4. 安装Postman,测试接口,https://cdn.liyanhui.com/data.json

二、RestFul

  1. RestFul Api 是一种设计风格,推荐的一种规范,有助于统一协同和管理;

  2. 这里提供两个网址

    RESTful API

    RESTful API 设计指南

    状态码使用规范

2.资源控制器和路由

一、资源控制器

  • 创建一个API-Controller
  • php artisan make:controller UserController --api

二、资源路由

  • 创建好 API 资源控制器之后,在route/web.php 配置相关api资源路由;

    Route::apiResourcce('users', 'UserController');

HTTP类型 路由URI 控制器方法 路由命名 描述
GET users index() users.index 获取数据列表
POST users store() users.store 创建页的接受处理
GET users/{user} show() users.show 获得一条数据
PUT/PATCH users/{user} update() users.update 从编辑页中接受处理
DELETE users/{user} destroy() users.destroy 删除一条数据

PS:可以通过 php artisan route:list 来查看资源路由列表

3.安装Laravel8.x

  • 使用 composer 创建

    composer create-project --prefer-dist laravel/laravel blog

  • 提前配置好 hosts 文件,然后运行下面命令

    php artisan serve --host www.lv8.com

  • 创建一个API-Controller

    php artisan make:controller UserController --api

    在UserController 中的 index 写个 return 'index';.

  • 然后再 routes/api.php中引入API-Controller

    php 复制代码
    use App\Http\Controllers\UserController;
    
    Route::apiResourcce('users', UserController::class);
  • 检查一下路由是否有效

    php artisan route:list

现在是可以请求 www.lv8.com:8000/api/users

4.生成标准API

专门创建一个API抽象类,并继承调用它。

生成标准API

  1. 创建一个抽象类 BaseController 实现一个生成API的方法,让控制器继承;

    php artisan make:controller BaseController

    php 复制代码
    /**
     * Class BaseController
     * @package App\Http\Controllers
     * api 基类
     */
    abstract class BaseController extends Controller
    {
        // 生成api方法
        protected function create($data, $msg = '', $code = 200)
        {
            // 返回api结果
            $result = [
                // 状态码
                'code' => $code,
                //自定义信息
                'msg' => $msg,
                // 数据返回
                'data' => $data
            ];
    
            return response($result, $code);
        }
    }
  2. UserController 中继承上面的抽象类

    php 复制代码
    class UserController extends BaseController
    {
        public function index()
        {
            return $this->create([1,2,3], '数据获取成功',200);  // 当前类是 BaseController 的子类,create是继承后的方法
    }

    继承后直接使用 $this 来调用抽象类的方法

5.数据列表和分页

数据列表返回

  1. 创建一个 Model/User ,用于数据库模型处理,用命令生成;

    php artisan make:model api/User

    php 复制代码
    // 空模型即可
    class User extends Model
    {
        use HasFactory;
    }
  2. 注意配置数据库连接,账号、密码、数据库名、前缀等

  3. 使用模型方式调用数据库链接,并返回数据

    php 复制代码
    // 在 UserController 中
    use App\Models\api\User;
    
    public function index()
    {
        $reslut = User::select('id', 'username', 'email')->get(); // 这里只要了三个字段
        return $this->create($reslut, '数据获取成功',200);
        
        // 使用 paginate 来进行分页
    //        return $this->create(User::select('id', 'username', 'email')->paginate(5), '数据获取成功',200);  // 这里是前五条数据
    //        return $this->create(User::select('id', 'username', 'email')->simplePaginate(5), '数据获取成功',200);  // 简洁版
    }

    注意:这里就已经连接数据库了。

    分页操作:没有太多需求的话,一般使用简单形式 simplePaginate.

    测试接口:http://www.lv8.com:8000/api/users?page=2

6.配置404错误

首先规范一下错误状态的状态码,具体说明如下:

  • 200(OK)-表示已在响应中发出
  • 204(无内容) - 资源有空表示,请求成功,但无数据
  • 301(Moved Permanently) - 资源的URI已被更新
  • 303 (See Other) -其他(如,负载均衡)
  • 304 (not modified) -资源未更改(缓存)
  • 400 (bad request)- 指代坏请求(如,参数错误)
  • 404 (not found)- 资源不存在(找不到页面)
  • 406 (not acceptable)- 服务端不支持所需表示
  • 500 (internal server error)- 通用错误响应
  • 503 (Service Unavailable)- 服务端当前无法处理请求

框架已经非常智能的提供了404的处理,只要固定路径配置 404 错误页即可;

覆盖掉系统自带的404:resources/views/errors/404.blade.php

php 复制代码
<?php
/*
 * API格式
 * path:resources/views/errors/404.blade.php
 * */
// 设置 HTTP 状态码为 404
http_response_code(404);

// 设置响应头为 JSON 格式
header('Content-Type: application/json');

$result = [
    // 状态码
    'code' => 404,
    // 自定义信息
    'msg' => '资源不存在~',
    // 数据返回, 返回一个空
    'data' => []
];

echo json_encode($result);  // 必须要加 json_encode 格式转换    

7.单数据处理及错误

  • 资源控制器中 show,表示获取单一数据,传递id参数即可

  • 那么,我们在show 方法里构造获取方式,具体如下:

    位置:UserController.php

    php 复制代码
    public function show($id)
    {
        // 判断id 合法
        if(!is_numeric($id)){
            return $this->create([], 'id参数错误!!!', 400);
        }
    
        // 获取数据
        $result = User::select('id', 'username', 'email')->find($id); // 通过id查找
        // 判断是否为空
        if(empty($result)){
            return $this->create([], '请求成功,但无数据~', 204);
    
        } else {
            return $this->create($result, '数据获取成功~', 200);
        }
    }

    PS:路由地址为:http://www.lv8.com:8000/api/users/20

注意,需要把 BaseController 中的 return修改一下

php 复制代码
class BaseController extends Controller
{
    // 生成api方法
    protected function create($data, $msg = '', $code = 200)
    {
        // 返回api结果
        $result = [
            // 状态码
            'code' => $code,
            // 自定义信息
            'msg' => $msg,
            // 数据返回
            'data' => $data
        ];

        return response($result);
    }
}

8.新增数据API处理

  • 新增一条数据,首先要进行验证,这里找事服务器端的,用验证器即可
  • 使用Postman来模拟新增时,选择Body中的form-data(表单),并用POST;

添加数据函数

php 复制代码
public function store(Request $request) // post 进入
{
    // 获取提交数据
    $data = $request->all();
    // 数据验证,required 不可为空, unique 唯一,
     $validator = Validator::make($data, [
        'username' => 'required|unique:users|min:2|max:10', // 2 < length < 10
        'password' => 'required|min:6', // x > 6
    ]);

    // 验证并提示
    if ($validator->fails()) { // fails 如果发生错误
//            return $this->create([], "提交的数据有误~", 400);
        return $this->create([], $validator->errors(), 400);  // $validator->errors() 是框架自带的错误提示英文
    } else {
        // 写入数据
        $addData = User::create($data);

        // 存在,说明成功了
        if ($addData) {
            return $this->create($data, '数据添加成功~', 200);
        }
    }
    return $data;
    // 数据验证
//        $validator
}

数据验证

规则 说明 示例
required 字段必填(非空) 'email' => 'required'
nullable 允许字段为 null 'phone' => 'nullable'
string 必须是字符串类型 'name' => 'string'
min:value 最小长度/值(字符串、数组、数值) 'password' => 'min:6'
max:value 最大长度/值 'username' => 'max:20'
email 验证邮箱格式 'email' => 'email'
unique:table 数据库唯一性校验 'username' => 'unique:users'
exists:table 值必须存在于数据库 'role' => 'exists:roles,name'
confirmed 字段名_confirmation 匹配 'password' => 'confirmed'
in:value1,value2 值必须在指定列表内 'status' => 'in:active,pending'
numeric 必须是数字 'age' => 'numeric'
date 验证日期格式(如 Y-m-d 'birthday' => 'date'
php 复制代码
// 用户名(必填+唯一+长度限制)
'username' => 'required|unique:users|min:2|max:10',

// 密码(必填+最小长度+确认)
'password' => 'required|min:6|confirmed'

// 邮箱(必填+格式验证)
'email' => 'required|email'

快捷记忆口诀

  • 必填非空required

  • 数据类型stringnumericinteger

  • 长度控制min/max/size

  • 唯一性unique(数据库校验)

  • 格式验证emailurldate

  • 二次确认confirmed(如密码确认)

许可赋值 App\Models\api;

php 复制代码
<?php

namespace App\Models\api;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    use HasFactory;
    // 许可赋值
    protected $fillable = ['username', 'password','email', 'details'];
}

9.删除数据API处理

删除API DELETE

  • API删除,使用DELETE动词既可
php 复制代码
public function destroy($id)
{
    // 判断id 合法
    if(!is_numeric($id)){
        return $this->create([], 'id参数错误!!!', 400);
    }
    // 查找数据,并删除 find
    $users = User::find($id);
    // 删除的数据不存在
    if(empty($users)){
        return $this->create([], '数据不存在~', 400);
    }

    // 执行删除返回
    if($users->delete()){
        return $this->create([], '数据删除成功~', 200);
    }
    return $this->create([], '请求成功,删除失败~', 200);
}

使用DELETE方式,请求地址:http://www.lv8.com:8000/api/users/20

Controller.

php 复制代码
<?php

namespace App\Http\Controllers;

use App\Models\api\client;
use Illuminate\Http\Request;

class ClientController extends BaseController
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        // 获取全部数据
        $data = client::select('id', 'email', 'password_hash', 'phone_number', 'first_name', 'last_name')->get();
        return $this->create($data, 'success', 200);

    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        // 验证请求数据
        $validatedData = $request->validate([
            'email' => 'required|email|unique:clients',
            'password_hash' => 'required',
            'phone_number' => 'required',
            'first_name' => 'required',
            'last_name' => 'required'
        ]);

        // 创建新的客户端记录
        $client = client::create($validatedData);

        return $this->create($client, 'Client created successfully', 201);
    }

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
        // 单数据处理
        // 判断id是否合法
        if(!is_numeric($id)){
            return $this->create([], 'id参数错误~', 400);
        }

        // 获取数据
        $reslut = client::select('id', 'email', 'password_hash', 'phone_number', 'first_name', 'last_name')->find($id);

        // 判断是否为空
        if(empty($reslut)){
            return $this->create([], '请求成功但无数据~', 200);
        }
        return $this->create($reslut, 'success', 200);
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, $id)
    {
        // 判断id是否合法
        if(!is_numeric($id)){
            return $this->create([], 'id参数错误~', 400);
        }

        // 查找要更新的客户端记录
        $client = client::find($id);

        if (!$client) {
            return $this->create([], 'Client not found', 404);
        }

        // 验证请求数据
        $validatedData = $request->validate([
            'email' => 'email|unique:clients,email,'.$id,
            'password_hash' => 'sometimes',
            'phone_number' => 'sometimes',
            'first_name' => 'sometimes',
            'last_name' => 'sometimes'
        ]);

        // 更新客户端记录
        $client->update($validatedData);

        return $this->create($client, 'Client updated successfully', 200);
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    {
        // 判断id是否合法
        if(!is_numeric($id)){
            return $this->create([], 'id参数错误~', 400);
        }

        // 查找要删除的客户端记录
        $client = client::find($id);

        if (!$client) {
            return $this->create([], 'Client not found', 404);
        }

        // 删除客户端记录
        $client->delete();

        return $this->create([], 'Client deleted successfully', 200);
    }
}

axios,用例

html 复制代码
<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<meta name="viewport" content="width=device-width, initial-scale=1">
	<title>Title</title>
	<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
	<style type="text/css">
		* {
			padding: 0;
			margin: 0;
		}

		table {
			font-size: 18px;
			border-collapse: collapse;
			width: 700px;
			height: 80px;
			margin: 0 auto;
			text-align: center;
		}

		th {
			width: 100px;
			height: 68px;
			padding: 8px 12px;
			background: yellowgreen;
		}

		table,th,td {
			border: 1px solid yellowgreen;
		}
	</style>
</head>
<body>
	<h1>表格</h1>
	<table class="table">
		<tr>
			<th>id</th>
			<th>username</th>
			<th>gender</th>
			<th>email</th>
			<th>price</th>
		</tr>
	</table>

	<script type="text/javascript">
		const table = document.querySelector(".table>tbody");
		let data_str = table.innerHTML;
		
		axios({
			method: 'get',
			url: 'https://cdn.liyanhui.com/data.json',
			// data: {}
		}).then((res) => {
			// data = res.data;
			res.data.forEach((value) =>{
				data_str += `<tr><td>${value.id}</td>
				<td>${value.username}</td>
				<td>${value.gender}</td>
				<td>${value.email}</td>
				<td>${value.price}</td></tr>`;
			})
			table.innerHTML = data_str;
		});
	</script>
</body>
</html>
相关推荐
app1e23428 分钟前
ctfshow web入门 php特性(89-115)
android·前端·php
深山技术宅3 小时前
Laravel 12 实现 OAuth2 登录
php·laravel
脆皮瞎4 小时前
phpstorm用php连接数据库报错
数据库·php·phpstorm
真正的醒悟12 小时前
IRF2.0&&IRF3.1
开发语言·网络·php
郑梓妍17 小时前
(持续更新)Ubuntu搭建LNMP(Linux + Nginx + MySQL + PHP)环境
linux·ubuntu·php
Haku Coder1 天前
网络安全零基础培训 L1-8 PHP基础语法
安全·web安全·php
安全系统学习1 天前
网络安全之浅析Java反序列化题目
运维·开发语言·网络·算法·安全·web安全·php
Haku Coder1 天前
网络安全零基础培训 L1-9 PHP连接MySQL数据库
数据库·web安全·php
YUJIANYUE2 天前
php+mysql活动报名学生选课产品预定旅游报名系统网站源码
mysql·php·旅游