在前后端分离架构中,PHP框架专注提供JSON接口,选型需结合前端路由模式、团队能力与部署环境:启用history模式需配置fallback路由;无全栈经验优先选ThinkPHP;受限环境避用Laravel命令行依赖;API响应须统一格式,跨域配置须匹配凭证需求,登录态应弃Session改JWT或Redis Token。

在前后端分离架构中,PHP框架不再负责渲染页面,而是专注提供结构清晰、响应迅速、格式统一的JSON接口,你需要快速判断哪个框架更适合当前项目节奏与团队能力。
选框架前必须确认的三件事
第一步:确认你的前端是否已明确使用 Vue 或 React 并启用 history 模式——若启用,后端必须配置 fallback 路由,否则刷新页面 404;Laravel 默认支持,ThinkPHP 需手动在 public/index.php 末尾追加 【if (!file_exists(__DIR__ . '/' . $_SERVER['REQUEST_URI'])) { require_once __DIR__ . '/index.php'; }】。
第二步:检查团队是否有 PHP 全栈经验。若前端同学会写 Laravel Blade,但没碰过 Axios 和 Promise,优先选 ThinkPHP —— 它的 json() 方法不依赖 response() 对象,直接 return json(['code'=>0]) 就能输出标准 JSON,容错率高。
第三步:看部署环境是否受限。共享主机或老旧 VPS 往往禁用 exec()、shell_exec(),而 Laravel 的队列监听、Artisan 命令行工具依赖这些函数;ThinkPHP 的定时任务可纯靠数据库时间戳 + 普通 HTTP 请求触发,更轻量。
立即学习“PHP免费学习笔记(深入)”;
API 响应体必须统一格式
方法一:Laravel 中全局封装(推荐)
在 app/Http/Controllers/Controller.php 的构造函数里写:protected $successCode = 200;,再定义一个 apiResponse($data, $code = null) 方法,内部调用 response()->json(['code' => $code ?? $this->successCode, 'msg' => 'ok', 'data' => $data]);所有控制器继承它即可。
方法二:ThinkPHP 6+ 使用中间件统一拦截
创建中间件 ApiFormat,注册到 api 分组,在 handle() 中对 $response->getContent() 做 JSON 解析→重包→再 encode,但注意:若控制器已 echo 或 exit,中间件失效;【务必在控制器最后 return,不要提前 echo】。
方法三:原生 PHP 粗暴但有效
在入口文件第一行写:header('Content-Type: application/json; charset=utf-8');,结尾统一写:exit(json_encode(['code'=>0,'msg'=>'success','data'=>$result], JSON_UNESCAPED_UNICODE));——简单直接,无框架依赖,适合快速验证逻辑。
跨域请求必须一次配准
第一步:确认前端请求是否带 Cookie 或 Authorization 头
如果登录用 JWT 放 Header,就设 allow_credentials => false,origin 可填 *;如果还混用 Session,就必须指定 origin 域名且 allow_credentials => true,否则浏览器直接拦截。
第二步:Laravel 必须安装 fruitcake/laravel-cors
执行 composer require fruitcake/laravel-cors,然后在 app/Http/Kernel.php 的 $middlewareGroups['api'] 数组里加入 \Fruitcake\Cors\HandleCors::class,别漏掉 OPTIONS 方法支持——否则 Vue 发送 PUT/DELETE 前的预检请求直接 403。
第三步:ThinkPHP 用 think-cors 扩展
运行 composer require topthink/think-cors,发布配置后编辑 config/cors.php,把 'origin' 设为 ['http://localhost:8080', 'https://your-vue-app.com'],生产环境严禁留 *;【一旦配置错误,Chrome 控制台只显示 net::ERR_FAILED,不会告诉你哪行错】。
验证码与登录状态必须放弃 Session
第一步:验证码改用 Redis + captcha_id 传递
生成时,后端生成随机字符串 $id = uniqid();,存入 Redis:Redis::setex('captcha:'.$id, 300, strtolower($code));,返回 JSON:['captcha_id' => $id, 'image' => 'data:image/png;base64,...'];前端提交时把 captcha_id 一起发过来,校验逻辑查 Redis::get('captcha:'.$captcha_id),比对后立即 Redis::del('captcha:'.$captcha_id)。
第二步:登录态改用 JWT 或 Redis Token
Laravel 推荐 tymon/jwt-auth,签发 token 后存在响应头 Authorization: Bearer xxx;ThinkPHP 可用 tp-jwt 扩展,或手写:生成 32 位唯一 token → 存 Redis(key=token, value=user_id)→ 设置过期时间 → 返回给前端;后续所有接口从 Authorization 头或 query 参数取 token 校验,不依赖 $_SESSION。
第三步:注销操作必须主动删 Redis 记录
不能只清客户端 localStorage,后端必须执行 Redis::del($token);否则 token 仍有效,存在越权风险。



















