# 2.2 Laragon 环境搭建 :::tip 概述 本项目推荐使用 Laragon 在 Windows 下搭建本地开发环境(Apache + PHP 8.3 + MySQL + Redis)。本页基于实际部署记录整理,涵盖 Laragon 目录结构、hosts 域名解析、Apache 虚拟主机配置、phpredis 扩展安装、php.ini 关键配置、Redis 密码与故障排查。完成本页后,即可进入 [2.3 后端服务启动](/zh/quickstart/backend-start.html)。 ::: ## 环境概况 | 项目 | 说明 | |------|------| | 操作系统 | Windows 10 / 11 | | 集成环境 | Laragon(如 `D:\laragon`) | | Web 服务器 | Apache 2.4(Laragon 内置,mod_php 方式) | | PHP | 8.3.x Win64 **TS(线程安全)**,项目要求 ≥ 8.3 | | 数据库 | MySQL 8.x(Laragon 内置) | | 缓存 | Redis(Laragon 内置,`127.0.0.1:6379`) | **关键目录:** ```text D:\laragon\www\ # 站点根目录(Apache 主 DocumentRoot) D:\laragon\bin\apache\httpd-2.4.x-...\ # Apache 主目录(下称 $HTTPD_HOME) D:\laragon\bin\php\php-8.3.x-Win32-vs16-x64\ # PHP 8.3 目录(下称 $PHP_HOME) D:\laragon\www\RXThinkCMF_Laravel13_EleVue\ # 项目根目录(下称 $PROJECT) ``` :::warning PATH 中的 php 版本陷阱 Laragon 默认 shell PATH 指向的可能是旧版 PHP(如 7.3),直接执行 `php artisan` 会报 `requires PHP >= 8.3`。执行 artisan、pint、composer 时**必须使用 8.3 的完整路径**: ```bash $PHP_HOME\php.exe artisan list $PHP_HOME\php.exe vendor\bin\pint --test ``` ::: ## 安装 PHP 8.3 1. 打开 Laragon 菜单 **PHP → Version**,选择 8.3.x; 2. 列表中没有 8.3 时,手动下载 `php-8.3.x-Win32-vs16-x64.zip`(**TS 线程安全版**,Laragon 的 Apache 以 mod_php 方式运行,必须用 TS),解压到 `D:\laragon\bin\php\` 下,重启 Laragon 后重新选择; 3. 验证版本与线程安全类型: ```bash $PHP_HOME\php.exe -v # PHP 8.3.x (ts) ... $PHP_HOME\php.exe -i | findstr "Thread Safety" # Thread Safety => enabled ← TS(Apache mod_php 需要) $PHP_HOME\php.exe -i | findstr "extension_dir" # extension_dir => D:/laragon/bin/php/php-8.3.x-Win32-vs16-x64/ext ← 记下扩展目录 ``` ## hosts 域名解析 编辑 `C:\Windows\System32\drivers\etc\hosts`(管理员权限): ```text 127.0.0.1 admin.laravel13.elevue file.laravel13.elevue ``` | 域名 | 用途 | |------|------| | `admin.laravel13.elevue` | 应用入口(DocumentRoot 指向项目 `public/`) | | `file.laravel13.elevue` | 附件目录(DocumentRoot 指向项目 `uploads/`) | 同系列项目域名格式为 `admin.<项目>.<前端品牌>`,如 `admin.laravel13.antdvue`、`admin.laravel13.naivevue`。 ## Apache 虚拟主机配置 ### 配置位置 `httpd.conf` 末尾有两处 Include,均可放置虚拟主机: ```apache IncludeOptional "D:/laragon/etc/apache2/sites-enabled/*.conf" # Laragon 自动生成 Include "conf/vhost/*.conf" # 手动配置(本项目在此) ``` 本项目使用 `$HTTPD_HOME\conf\vhost\laravel13.conf`。 ### 配置模板(Directory 块缺一不可) ```apache # 项目应用本地虚拟主机配置 ServerAdmin rxthinkcmf@163.com ServerName admin.laravel13.elevue DocumentRoot "D:\laragon\www\RXThinkCMF_Laravel13_EleVue\public" ErrorLog "logs/laravel13-error.log" CustomLog "logs/laravel13-access.log" common AllowOverride All Require all granted # 项目附件目录本地虚拟主机配置 ServerName file.laravel13.elevue DocumentRoot "D:\laragon\www\RXThinkCMF_Laravel13_EleVue\uploads" ErrorLog "logs/laravel13-error.log" CustomLog "logs/laravel13-access.log" common AllowOverride All Require all granted ``` ### 为什么 Directory 块必须写(404 根因) 主 `httpd.conf` 中的默认设置为 `AllowOverride None`(全局忽略 `.htaccess`)。Apache 的 `` 写在某个 `` 内部时**只对该虚拟主机生效**,因此 vhost 必须自带 `` 块,把本虚拟主机范围内的 `AllowOverride` 覆盖为 `All`,Laravel 的 `public/.htaccess`(URL 重写规则)才能生效。 **症状特征(识别此问题的关键):** ```text GET / → 200 正常(DirectoryIndex 命中物理文件 index.php) GET /api/captcha → 404,且是 Apache 原生 HTML 404 页 404 Not Found(不是 Laravel 的 JSON 响应) ``` 解读:物理文件能访问、非物理 URL 无法重写进 `index.php`,说明请求根本没有进入 Laravel。**只要 404 页面是 Apache 原生的,问题一定在 Web 服务器配置,而不是 Laravel 路由。** ### 配置校验与重启 ```bash # 改动配置后必做:校验语法(输出 Syntax OK 即通过;AH00112 警告可忽略) $HTTPD_HOME\bin\httpd.exe -t # Apache 未注册为 Windows 服务,-k restart 会报 "No installed service",需手动重启: taskkill //F //IM httpd.exe cmd //c start "" "D:\laragon\bin\apache\httpd-2.4.x-...\bin\httpd.exe" # 验证进程(应看到 2 个 httpd.exe:父进程 + 工作进程) tasklist //FI "IMAGENAME eq httpd.exe" ``` :::tip Laragon 菜单 **Apache → Reload** 亦可;手动部署环境下以上命令最可靠。 ::: ## 安装 phpredis 扩展 项目强依赖 Redis(验证码、JWT 会话、字典缓存),PHP 必须安装 redis 扩展,否则报 `Class "Redis" not found`。 ### 判断线程安全类型(决定下载哪个包) ```bash $PHP_HOME\php.exe -i | findstr "Thread Safety" # Thread Safety => enabled → TS 包(Laragon 的 Apache 用 TS) # Thread Safety => disabled → NTS 包(php-fpm 用) ``` ### 下载 官方 Windows 扩展仓库(`windows.php.net` 会 302 跳转到 `downloads.php.net`): ```text https://downloads.php.net/~windows/pecl/releases/redis/ # 目录按版本号分子目录:6.0.0/ 6.1.0/ 6.2.0/ 6.3.0/ ... ``` 文件名命名规则(**四个要素必须全部匹配**): ```text php_redis-{扩展版本}-php-{PHP主次版本}-{ts|nts}-vs16-{x64|x86}.zip 本次实际下载(PHP 8.3 + TS + 64 位 + VS16 编译器): https://downloads.php.net/~windows/pecl/releases/redis/6.3.0/php_redis-6.3.0-8.3-ts-vs16-x64.zip ``` ### 安装 ```bash # 解压后将 php_redis.dll 复制到扩展目录 copy php_redis.dll D:\laragon\bin\php\php-8.3.x-Win32-vs16-x64\ext\ ``` ### php.ini 配置 编辑 `$PHP_HOME\php.ini`(mod_php 与 CLI 共用同一份),在扩展区按字母序新增一行: ```ini extension_dir = "D:/laragon/bin/php/php-8.3.x-Win32-vs16-x64/ext" ... ;extension=pgsql extension=redis ← 新增此行(PHP 8 写法:不带 php_ 前缀和 .dll 后缀) ;extension=shmop ``` :::danger 常见坑 - 写成 `extension=php_redis.dll` 是 PHP 5 时代的旧写法,PHP 8 下报错; - 只改 `php.ini-development` / `php.ini-production` 无效,PHP 加载的是 `php.ini`; - **改完必须重启 Apache**(mod_php 常驻进程,不会热加载)。 ::: ### 验证 ```bash # CLI 验证(应输出 redis) $PHP_HOME\php.exe -m | findstr redis # HTTP 验证(重启 Apache 后调用依赖 Redis 的接口,见下方「部署验证清单」) ``` ## php.ini 关键配置 `$PHP_HOME\php.ini` 中与本项目相关的关键配置: | 配置项 | 建议值 | 说明 | |--------|--------|------| | `extension` 系列 | 按需启用 | 项目必需:`pdo_mysql`、`mbstring`、`gd`、`bcmath`、`zip`、`redis`、`openssl`、`fileinfo`、`curl`;跨库迁移目标为 PostgreSQL 时另启用 `pdo_pgsql` | | `memory_limit` | `256M` | Excel 导出等大内存场景 | | `max_execution_time` | `60` | 导入导出超时上限 | | `upload_max_filesize` / `post_max_size` | `50M` | 与 `.env` 中 `FILE_MAX_SIZE` 配合(业务限制更小) | | `date.timezone` | `Asia/Shanghai` | 与应用时区一致 | | `opcache.enable` | `1` | 本地开发可保持 `opcache.validate_timestamps=1`,改代码即时生效 | 修改后重启 Apache 生效。 ## Redis 密码配置 ### 状态确认 ```bash tasklist //FI "IMAGENAME eq redis-server.exe" # 进程 netstat -an | findstr ":6379" # 应看到 127.0.0.1:6379 LISTENING ``` ### 设置密码(实际踩坑记录) :::warning Redis 无密码直连可用;一旦在 Redis 侧设置了 `requirepass` 而 `.env` 未同步,Laravel 所有 Redis 操作(验证码、JWT 会话、限流)会全部失败,且 CaptchaService 的 catch 会把真实错误吞掉,只报「验证码生成失败 / 验证码服务不可用」。 ::: 处理步骤(缺一不可): 1. Redis 服务端设置密码(`redis.conf` 的 `requirepass` 或 `CONFIG SET requirepass`); 2. `.env` 同步配置: ```ini REDIS_CLIENT=phpredis REDIS_HOST=127.0.0.1 REDIS_PASSWORD=你的密码 ← 原为 null,必须改 REDIS_PORT=6379 ``` 3. 清除配置缓存并重启 Apache: ```bash $PHP_HOME\php.exe artisan config:clear ``` ### 单独验证 Redis 连通(绕开业务代码) ```bash $PHP_HOME\php.exe artisan tinker --execute="try { \Illuminate\Support\Facades\Redis::setex('test:key', 10, 'ok'); echo 'OK: '.\Illuminate\Support\Facades\Redis::get('test:key'); } catch (\Throwable \$e) { echo get_class(\$e).': '.\$e->getMessage(); }" # 输出 OK: ok 即连接正常(测试键 10 秒自动过期) ``` ## 部署验证清单 按顺序全部通过即环境就绪: ```text □ $PHP_HOME\php.exe -v → PHP 8.3.x (ts) □ $PHP_HOME\php.exe -m | findstr redis → redis □ httpd.exe -t → Syntax OK □ tasklist 查看 redis-server.exe → 进程存在,6379 LISTENING □ curl http://admin.laravel13.elevue/api/captcha → {"code":0,"ok":true,"msg":"操作成功","data":{...}} □ curl -X POST http://admin.laravel13.elevue/api/login → {"code":1,"ok":false,"msg":"参数验证失败","data":{...}} (路由已通) ``` 验证码接口返回 `code=0` 的 JSON 即部署成功——它同时验证了 Apache 重写、PHP 8.3、Redis 连通三条链路。 ## 常见问题 | 症状 | 原因 | 处理 | |------|------|------| | `/` 正常,`/api/*` 返回 Apache 原生 HTML 404 | vhost 缺 `` 块,`.htaccess` 被忽略 | 补 `AllowOverride All` 块,`httpd -t` 后重启 Apache | | `Class "Redis" not found` | PHP 缺 redis 扩展 | 装 `php_redis.dll` + `php.ini` 加 `extension=redis` | | 验证码生成失败 / 服务不可用 | Redis 密码不匹配或服务未启(日志里真实错误被 catch 吞掉) | `.env` 配 `REDIS_PASSWORD`,tinker 单测 Redis 连通 | | artisan/pint 报 requires PHP >= 8.3 | shell PATH 的 php 是旧版 | 用 `$PHP_HOME\php.exe` 完整路径调用 | | `httpd -k restart` 报 No installed service | Apache 未注册 Windows 服务 | `taskkill` 后重新启动 `httpd.exe` | | 改了配置 / 扩展不生效 | mod_php 常驻不热加载 | 必须重启 Apache | ## 相关页面 - [2.1 开发环境准备](/zh/quickstart/environment.html) — 版本要求总览 - [2.3 后端服务启动](/zh/quickstart/backend-start.html) — 安装依赖、初始化项目 - [2.6 环境变量配置](/zh/quickstart/env-vars.html) — `.env` 全部配置项说明 - [2.9 常见问题 FAQ](/zh/quickstart/faq.html) — 更多启动期问题