简介:一份面向 PHP 开发者的 CRMEB 多商户电商系统完整安装包,版本 V3.0.1。它基于 CRMEB 框架,内置商品管理、订单处理、支付集成、用户与多商户管理、营销活动等电商平台必备功能,适合需要快速搭建多商户平台的企业或技术团队。压缩包共 2000 个文件,大小约 295MB,包含 885 个 JavaScript、287 个 CSS 样式等前端资源,311 个 JSON 配置,254 个 Markdown 说明和 158 个文本文件,另附 3 个 Shell 自动化脚本与 2 个 SQL 数据库文件,便于部署和初始化;同时还包含 XML、HTML 以及多种格式的配置与文档资料。目录结构清晰,app 目录承载 MVC 核心代码,route 管理路由,crmeb 目录含框架核心,backup 用于数据备份,install 提供安装向导;配合 README 和 composer 依赖配置,可快速完成部署检查、依赖安装和二次开发。已有 354 人浏览学习,适合具备一定 PHP 基础、希望直接上线或继续扩展功能的开发者。整体以源码、配置、文档和脚本组合,提供完整的自动化安装与备份恢复思路,可显著缩短多商户电商平台的搭建周期。
1. crmeb多商户PHP安装包V3.0.1到底能装出一个什么系统
crmeb多商户PHP安装包V3.0.1是一套能直接部署到云服务器或虚拟主机的多商户商城系统,装完以后你得到的是一个平台加多个商户独立后台的B2B2C结构:平台方管审核、结算、营销,商户自己管商品、订单、对账。适合做本地生活、批发入驻、卖课程或做招商加盟。我不是第一次接触这个包,很多团队是买了授权源码直接开始改,结果卡在环境、权限和队列上。这篇按我自己的部署路径讲:从看懂安装包结构,到命令行安装,到上线前配置和最常见的翻车点。全文用的都是常见 LAMP/LNMP 环境,新手跟着做也能跑通。
2. 装这套PHP商城前:环境选型与安装包结构
2.1 运行环境:为什么我建议 PHP 7.4 + MySQL 5.7 + Nginx
这一版安装包是典型的 ThinkPHP 目录风格,虽然我不在这篇里写死框架版本号,但你从 composer.json 能确认。这类商城项目对运行环境有两个硬要求:PHP 的版本不能太低,低版本不支持命名空间、composer 自动加载和一些语法糖;也不能直接上 PHP 8.2 甚至 8.3,老代码在 PHP 8 下最常见的表现是静态方法调用、隐式类型转换、字符串拼接处报 deprecated 甚至 fatal。我一般建议先用 PHP 7.4 跑通,稳定后再考虑升级。
数据库方面,MySQL 5.7 是最省心的选择。crmeb 多商户有商户端、平台端、用户端三端查询,订单表、商品表、用户表都会参与 join,5.7 的优化器处理这类查询足够。MySQL 8 并不是不行,但有些旧代码用了sql_mode相关的写法,8 的默认 sql_mode 更严格,安装时可能出现“字段默认值”类报错。虚拟主机用户先问清楚 MySQL 版本再下单,别等装到一半翻车。
Web 服务器优先 Nginx。因为这套系统的 URL 是 pathinfo 风格(index.php/xxx/yyy),Nginx 配伪静态比 Apache 的 .htaccess 更可控,并发静态资源能力也强。Apache 用户不是不能用,只是当我遇到“首页能开、路由 404”的反馈时,十有八九是 .htaccess 不生效或伪静态规则没贴对。
PHP 扩展需要 fileinfo、opcache、redis、pdo_mysql、mbstring、gd/imagick 这几个。fileinfo 用于商品详情上传时校验 mime 类型,redis 用来做缓存和队列。php -m可以快速确认,不要漏。下面这段命令可以直接跑:
php -v # 确认版本,例如 PHP 7.4.33 php -m | grep -E '^phpredis|redis|fileinfo|pdo_mysql|mbstring|opcache|gd$' # 缺哪个扩展就装哪个,Debian/Ubuntu 用 apt,CentOS 用 yum命令里我特意把^phpredis|redis放在前面,因为有些系统的扩展名显示成redis,有些显示phpredis,两个我都接受。如果你看到这一行没有任何输出,说明扩展没装,后面会在安装向导的“环境检测”阶段直接卡住。先确认扩展,再传代码,这是我最常提醒的。
选环境时还必须考虑内存。这套系统不是单文件应用,PHP-FPM、MySQL、Redis 同时在一个 1G 内存的云主机上会非常紧张。我实际部署过的配置是 2G 内存起步,PHP-FPM 进程数按pm.max_children = 20左右设,MySQL 的 innodb_buffer_pool_size 给 512M,Redis 控制在 128M 以内。内存不够时表现出来的不是安装失败,而是后台页面点开越来越慢,最后进程被杀。
2.2 解压后先看哪些文件:安装包的常见结构与应用根目录
拿到 crmeb 多商户 PHP 安装包 V3.0.1 后,第一件事不是传到服务器,而是本机解压看一眼整体结构。常见做法是安装包外层有两个一级内容,一个是源码目录,一个是安装说明。源码目录里你会看到public目录,它是唯一需要被 Web 服务器指认的入口目录;很多第一次用的人把域名直接指向源码根目录,导致访问时 nginx 找不到 index 入口,于是出现 403 或者把 config 目录暴露出来。
我一直强调一个习惯:把 site 根指向public,而不是项目根目录。原因是这套系统的入口文件在public/index.php,同时上传目录、二维码生成目录都在 public 下面。如果把项目根目录直接设为站点根,不只是路由问题,还会让.env、config这类敏感文件处于可访问范围,除非你把 nginx 的 deny 规则写全,否则很别扭。
安装包解压后值得先看的文件有这几个:env.sample或.env.example这种环境变量模板,composer.json和composer.lock用来固定依赖,sql目录里通常是初始化 SQL(有的包会把它放在数据库目录),README或安装说明.txt里写了这个包的基础配置要求。先看这三个,基本就知道这一版需要 PHP 版本、扩展依赖和伪静态要求了。
这里要提醒一点:网上能找到的一些“安装包”代码不完整,比如缺vendor目录,比如缺public里的install目录。V3.0.1 的安装通常走/install在线向导,但有些精简包把 install 拿掉了,需要你手工导入 SQL 并配置.env。如果解压后没有发现安装向导目录,我的建议是直接找授权方要完整包,不要自己去拼,拼出来的系统后面升级有心无力。
2.3 哪些配置在安装前就要改:PHP 上传限制与超时
安装向导会把大部分配置做进 Web 界面,但 PHP 层有两个参数必须在命令行改好,否则安装过程会在“上传图片”或“导入 SQL”步骤莫名其妙断掉。第一个是upload_max_filesize,多商户系统安装时要上传图标、开屏图,存量商品数据也可能通过导入方式进来,默认 2M 通常不够;第二个是max_execution_time,安装向导要创建几十张表、初始化默认数据,网络慢或服务器负载高时 30 秒会超时。
我一般把这两个值和 post 大小一起改,加在php.ini的[PHP]段:
upload_max_filesize = 20M post_max_size = 20M max_execution_time = 300 memory_limit = 256Mmemory_limit改成 256M 是为了 composer install 和后台生成报表时不被掐断。改完之后用php -i | grep upload_max_filesize验证,但注意这个值有没有生效要看两个地方:一个是命令行 PHP 的php.ini,另一个是 PHP-FPM 使用的php.ini。很多虚拟主机是两套文件,网上有帖子说改了没生效,基本是这个原因。
除了 PHP 层,还需要确认服务器时间。商城系统的定时任务、券过期、订单超时关闭都对时间敏感,CST 和 UTC 差 8 小时会让所有“今天 0 点”的计算出错。用date命令看服务器时间,不对就用tzselect或改/etc/localtime,这一步虽然基础,但我每次都会做,因为它不会在安装时暴露,只会在上线后以“优惠券过期时间不对”的形式出现。
到这里,环境准备就算结束。我的判断标准很简单:php -m无缺项、站点根指向 public、上传和时间无隐患。这三件过了,再开始走安装向导。
3. 把 V3.0.1 跑起来:命令行部署的完整步骤
3.1 解压上传与目录权限:两条命令解决 80% 的安装报错
服务器上传源码时,推荐用 tar 打包后传输,不要直接在服务器上解压 zip,zip 的属主和软链接处理容易出问题。如果你的本地装的是 macOS 或 Linux,可以直接用 tar;Windows 本地可以先打成 zip 上传,再到服务器上用 unzip 解压,但解压完一定要处理属主。
常见做法是把源码放在/www/wwwroot/crmeb下,然后执行下面两条命令:
cd /www/wwwroot tar -zxf crmeb_mp_v3.0.1.tar.gz mv crmeb_mp_v3.0.1 crmeb chown -R www:www crmeb chmod -R 755 crmeb chmod -R 777 crmeb/public我解释一下这里的逻辑:chown -R www:www是把整个目录属主交给 PHP-FPM 的运行用户,这一步不做的后果是安装向导报“目录不可写”。chmod -R 755是给目录可读可进入权限,给 PHP 文件可执行权限的另一种说法;chmod -R 777 crmeb/public是为了让上传、缓存、二维码目录能写,很多安装包在 public 下存在runtime或upload目录,它们是程序运行期间要写文件的地方。
需要特别说明:777 不是越给得多越好,而是因为 PHP-FPM 和命令行执行任务(crontab)可能由不同用户运行,755 只保证读和进,不保证写。我更习惯的做法是只对要写的具体目录放开写权限,比如public/runtime、public/upload,但第一次安装图省事直接给 public 777 也没问题,装完再收权限。
这里有个细节:如果你用 root 解压,chown -R www:www之后,命令行的 crontab 如果也以 www 用户运行,就能写同一个缓存目录,否则你会遇到“后台能操作,但队列任务报权限错误”的怪问题。后面第 5 章我会再展开。
3.2 创建数据库与账号:给安装器一个最小权限的原则
安装向导通常要求你填一个 MySQL 账号和密码。为了让数据库密码不被写在一堆日志里,我建议单独建一个账号,只授权当前这一个库,不要用 MySQL root。这样即使 .env 泄露,攻击者也只能动商城库,不能碰系统库。
创建命令:
CREATE DATABASE crmeb_mp DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; CREATE USER 'crmeb_user'@'localhost' IDENTIFIED BY '这里写一个强密码'; GRANT ALL PRIVILEGES ON crmeb_mp.* TO 'crmeb_user'@'localhost'; FLUSH PRIVILEGES;字符集我明确用 utf8mb4,因为商品数据里可能包含 emoji、生僻字、多语言姓氏;如果被安装向导里的默认 latin1 带偏了,后面插入特殊字符会报“Incorrect string value”。排序规则用utf8mb4_general_ci在性能上比utf8mb4_unicode_ci略好,做中文商城完全够用,排序精度差别你几乎感知不到。
数据库账号我给了GRANT ALL PRIVILEGES ON crmeb_mp.*,这里没有给全局所有库的权限,是刻意控制风险。安装向导在导入 SQL 时只需要建表、加索引,不需要远征其他库。如果安装过程中报“权限不足”,先检查账号的 host 是不是localhost,很多云数据库需要写%,这是环境差异,不是 bug。
如果你用的是云厂商的 RDS,CREATE USER 和 GRANT 都在云控制台操作,命令行的语法可能有些差异。我的建议是:无论哪家,先把排序规则设为 utf8mb4,并在控制台把“自动备份”打开。安装包里的 SQL 导入是一次性的,之后你的数据得靠备份制度兜底。
3.3 网页安装向导配置:填写项逐项说明
数据库建好后,在浏览器访问http://你的域名/install,正常情况下会看到一个环境检测页。检测项无非是 PHP 版本、扩展、目录权限,如果前面 2.1 和 2.2 都做对了,这一步是一路绿色的。少数环境检测会把“未安装 Fileinfo”之类标红,先回第 2 章补扩展,不要跳过。
向导第二步会要求填数据库信息,我一般这样填:
| 配置项 | 推荐值 | 说明 |
|---|---|---|
| 数据库地址 | 127.0.0.1 或 RDS 内网地址 | 别填 localhost 以外的公网域名 |
| 数据库端口 | 3306 | 云数据库可能不是默认端口 |
| 数据库名 | crmeb_mp | 第 3.2 步创建的库 |
| 数据库用户名 | crmeb_user | 最小权限账号 |
| 数据库密码 | 刚才设置的强密码 | 避免使用弱口令 |
填完这些,安装器会开始建表并写入初始数据。这一步最怕的是中途断网、超时或 PHP 被掐,所以前面 max_execution_time 很关键。如果你用的是带面板的服务器,建议把 PHP 的超时从面板里也同步改一遍,因为面板的 PHP 配置可能覆盖命令行配置。
安装的最后一步通常是设置平台管理员账号和密码,以及选择网关。管理员账号我建议用一个独立邮箱,不要用绑定了个人手机号的账号;网关这一步可以先选“测试模式”或“手动支付”,等系统跑通了再切真实支付参数。有些安装包这一步还会让你填“平台名称”和“LOGO”,这是元数据,后续在后台都可以改,不用想太久。
安装成功后,页面会提示你删除public/install目录。我见过有人嫌麻烦不删,结果别人访问/install时看到的是“重新安装”提示,更危险的是可以重新执行安装、覆盖数据库。所以安装完成后的第一命令应该是:
rm -rf /www/wwwroot/crmeb/public/install这个目录不删,等于把系统后台的钥匙放在门口。我每次安装完会再访问一次/install,确认返回 404 才算收工。
3.4 Nginx 伪静态配置:路由才不走丢
安装向导完成后,首页可能立刻能打开,但点进“商家入驻”或某个商品详情时出现 404,这通常是伪静态没有生效。crmeb 多商户这套系统的 URL 是 pathinfo 风格,Nginx 需要把请求重新解析给index.php。
常见配置如下:
server { listen 80; server_name crmeb.example.com; root /www/wwwroot/crmeb/public; index index.php; location / { if (!-e $request_filename) { rewrite ^/(.*)$ /index.php/$1 last; } } location ~ \.php(/|$) { fastcgi_pass 127.0.0.1:9000; fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_path_info; } }注意root一定要指到public,这是第 2.2 节反复强调的入口。fastcgi_split_path_info那句是给 PHP 传 PATH_INFO 的,没有它,pathinfo 路由会全部失效。如果你的环境是宝塔或类似面板,后台的 PHP 伪静态规则通常已经内置了这套,你只需要在站点设置里选择对应框架或 ThinkPHP 规则即可。
这一版安装包有时候也会出现“后端能访问、前端 404”的现象,先不要怀疑代码,先检查 nginx 配置后重新加载:nginx -t && nginx -s reload。配置加载是经常被忽略的一步,改完不 reload 等于没改。
到这里,一套完整的多商户商城已经可以在浏览器里访问了。但距离真正在线运营还差很多,因为订单创建后的回调、短信发送、自动结算都靠队列和定时任务驱动,这就是下一章要讲的配置重点。
4. 装完后的关键配置:伪静态、队列、定时任务与商户域名
4.1 .env 文件参数:数据库、Redis、缓存驱动
安装向导会在项目根目录生成一个.env文件,它相当于整个系统的配置中心。V3.0.1 这类包里,数据库连接、Redis、缓存驱动都在这个文件里。不同安装包的键名略有差异,但常见会包括APP_DEBUG、DATABASE_HOST、DATABASE_NAME、REDIS_HOST这些。打开文件后建议按下面调:
APP_DEBUG = false APP_TRACE = false DATABASE_HOST = 127.0.0.1 DATABASE_NAME = crmeb_mp DATABASE_USER = crmeb_user DATABASE_PASSWORD = 你的强密码 DATABASE_PORT = 3306 REDIS_HOST = 127.0.0.1 REDIS_PORT = 6379 REDIS_PASSWORD = REDIS_SELECT = 0APP_DEBUG上线前必须改成 false,否则错误信息会把堆栈、数据库语句、甚至部分环境路径直接显示给用户,这对商城很危险。调试阶段可以先保持 true,但每次改 .env 之后要清一下缓存,不然配置不生效。
REDIS_PASSWORD留空表示本机 Redis 无密码。如果你用了云 Redis,一定要填密码。REDIS_SELECT是 Redis 库序号,商城项目的 session、缓存、队列可能会用不同库号,这个序号要跟后台设置里的队列驱动保持一致;如果程序里配置的队列库是 1,而 .env 里 REDIS_SELECT 是 0,会出现“后台能看到订单,队列消费不到消息”的怪事。
缓存驱动方面,安装向导一般会让你在文件驱动和 Redis 驱动之间选。我建议选 Redis,因为多商户系统涉及权限缓存、菜单缓存、配置缓存,文件缓存会在高并发下生成大量碎文件,清文件缓存的命令也会因为权限问题经常失败。选 Redis 之后,缓存和队列可以共用同一个 Redis 实例,只要库号分开就行了。
改完 .env 记得执行一次清缓存命令。常见做法是两个命令:
php think clear php think cache:clear这两个命令的作用不同:php think clear清框架运行时缓存,php think cache:clear清业务缓存;有些版本的命令只在 console 应用内可用,如果你不确定,两个都跑总没有坏处。清完后用浏览器打开后台看菜单是否正常,出现数据连接错误就先检查 .env 里的账号密码和 RDS 端口。
4.2 队列监听:订单/短信异步任务必须跑起来
商城系统的短信验证码、支付回调处理、订单队列、分销分佣结算,默认都不是同步处理的,而是把任务往队列里一丢,由后台进程慢慢消费。如果队列没跑,表现是“用户能下单但收不到短信”“支付成功后订单状态不变”这类只报后台、不报前台的慢性问题。
V3.0.1 这版多商户包的命令入口一般是php think queue:listen,具体进程名以你安装包里的think命令为准。我常用的启动方式是:
php think queue:listen --tries=3 --queue=crmeb这里--tries=3表示每条任务最多重试 3 次,避免网络抖动导致的临时失败直接把任务丢进死信。--queue=crmeb是指定消费名为 crmeb 的队列通道。如果你的服务器没有 Redis,可以退回到数据库驱动,但我不推荐,因为数据库驱动轮询队列会产生额外的锁和 IO。
queue:listen 不能靠 SSH 挂一个前台进程,因为终端一关进程就没了。正经做法是用 supervisor 守护。下面是一个 supervisor 配置片段:
[program:crmeb-worker] process_name=%(program_name)s_%(process_num)02d command=php /www/wwwroot/crmeb/think queue:listen --tries=3 --queue=crmeb directory=/www/wwwroot/crmeb autostart=true autorestart=true numprocs=2 user=wwwnumprocs=2表示起两个进程消费队列。如果只有一个进程,短信和订单回调夹杂着来,延迟就不稳定;起太多也没必要,多商户初期 2 个足够。user=www是为了和 PHP-FPM 写缓存目录的属主一致,避免队列进程以 root 身份写入 runtime 目录,造成目录属主混乱后,后台无法删除该目录。
配置完后执行supervisorctl reread && supervisorctl update再supervisorctl status。如果你把queue:listen写错了,supervisor 会自动重启,不断输出错误日志,这时用supervisorctl tail -50 crmeb-worker看近期日志,第一行报错通常就是原因。
4.3 定时任务:结算、关闭未支付订单的 crontab
队列负责“实时性”任务,而定时任务负责“周期性”任务,比如自动关闭未付款订单、每月结算商户账单、清理过期日志。在 crmeb 多商户后台,你会在系统设置里看到定时任务清单,每个任务对应一个 cron 表达式和一条think命令,但这些命令不会自己挂到 crontab 里去,需要你手动添加。
我通常把定时任务统一放到系统 crontab:
*/1 * * * * www /usr/bin/php /www/wwwroot/crmeb/think task:crontab >> /www/wwwroot/crmeb/runtime/log/crontab.log 2>&1命令路径要写绝对路径:/usr/bin/php是你which php查到的实际路径,/www/wwwroot/crmeb/think是项目路径。相对路径在 crontab 里几乎没有可用性,因为 crontab 的默认工作目录不是站点目录。
task:crontab是常见的总入口,它会把后台配置好的所有定时任务拉起;有的版本里这个命令叫crontab或task,你可以先php think list看命令列表。日志重定向到 runtime/log 下是为了出问题时能排查,定时任务失败往往没有返回值,不看日志永远不知道发生过。
设置好 crontab 后,我一般会手动运行一次上面这条命令,如果输出里有错误就当场处理。定时任务的运行用户是 www,而不是 root,这样生成的缓存文件属主一致。如果你发现日志显示“Permission denied”,就先检查 crontab 里用户名是否写对,很多面板会默认以 root 执行,而非 root 用户下写缓存就会出问题。
4.4 商户端域名与图片域名:多店后台和用户端怎么绑定
多商户和单商户商城最大的配置差异在于:除了平台端,每个入驻商户可能有独立的商家后台地址,有些运营模式还要求商户店铺有独立二级域名或独立小程序码。V3.0.1 安装包通常在平台后台的“设置-商城设置”里有一个“绑定域名”的配置,包括 H5 端域名、商家端域名、图片域名。
图片域名是个容易翻车的点。我的建议是:不要把图片域名的地址写成和站点域名完全一致,除非你已经单独规划了静态 CDN。原因在于后端上传时会生成完整的图片 URL 存入数据库,如果以后要切换到 OSS 或 CDN,你得批量改数据库里的图片地址,那是很痛的操作。如果一开始就把图片域名和商城域名分开,比如img.example.com走静态文件,后面平滑切换会容易得多。
商家端域名配置上,首先要确保域名已解析到这台服务器,并在 Nginx 里增加 server 块,root 同样指向 public,伪静态规则和主站点一致。有些运营方只给商户提供一个目录子路径,比如example.com/merchant,这种配置往往需要安装包里有路由前缀支持,没有的话更省事的方法是给商户后台单独绑定二级域名。
还有一个细节是 Redis 缓存里的域名信息。改完域名配置后,后台可能还是显示旧域名,这不是没保存成功,是缓存没有失效。到后台找到“清除缓存”按钮再点一次;没有按钮就用 4.1 的命令行缓存删除命令。域名配置最常见的问题就是改完不刷缓存,我自己踩过不止一次,所以把它写在这里。
5. 部署 crmeb 多商户 V3.0.1 避坑记录:5 个常见问题
5.1 安装向导提示“目录不可写”但我的权限已经 777
现象:环境检测前几步都绿了,到上传目录或 runtime 目录时显示“不可写”,用ls -al看目录权限确实已经是 777。
原因:权限 777 只控制读、写、执行,不控制属主和文件系统 ACL。多数服务器面板里 PHP-FPM 运行在www用户下,而你以 root 或自己的账号解压了源码,文件属主是 root,虽然 777 让其他用户也能写,但 Nginx/Apache 的工作进程有时会受open_basedir或 SELinux 限制,组合起来照样写不进去。
解决:把属主改成 PHP-FPM 用户,并同时检查 SELinux 状态。命令如下:
chown -R www:www /www/wwwroot/crmeb setsebool -P httpd_can_network_connect 1 2>/dev/nullsetsebool那行在 SELinux 开启时才需要。如果系统没有安装 SELinux,命令会失败,但没有副作用。改完属主后再刷新安装页;如果你是虚拟主机,没有命令行权限,就从面板的“文件管理”里选择所有文件,把属主改为“php-fpm 用户”。这个问题在 Windows 服务器上还会伴生“目录名大小写”问题,V3.0.1 的路径区分大小写,Public和public的写法不要混。
5.2 安装时“创建数据表失败”或导入 SQL 到一半中断
现象:安装向导到初始化数据时,报“SQL 文件执行失败”或长时间卡住,再刷新提示数据库存在,但后台登录账号不存在。
原因:常见是 MySQL 的max_allowed_packet太小,安装 SQL 里包含较大 BLOB(例如模板、图片 base64),数据包超过限制后被 MySQL 拒绝;另一种可能是数据库账号权限不足,无法创建触发器或索引。
解决:先调大 MySQL 参数,再重建库。重建库时不要在安装向导里填已有库,最好先删掉半成品库:
DROP DATABASE IF EXISTS crmeb_mp; CREATE DATABASE crmeb_mp DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;然后改 MySQL 配置:
[mysqld] max_allowed_packet = 64M改完重启 MySQL,再重新走安装向导。如果仍然在触发器那一步失败,检查账号是否有TRIGGER权限,云数据库控制台里建账号时要勾选所有权限,别只勾 SELECT/INSERT/UPDATE/DELETE。
5.3 首页能打开,商品详情和商户入驻全部 404
现象:商城首页正常,但点击任何需要路由解析的链接都 404,后台却能打开(因为后台通常用独立的入口或自带伪静态)。
原因:Nginx 没有配置 pathinfo 支持。crmeb 多商户的目标 URL 是/index.php/goods/detail/xxx这种形式,Nginx 默认会尝试按物理路径找同名文件,找不到就直接 404,而不会转交给 PHP。后台之所以能开,是因为后台入口可能走/admin或/merchant被 Rewrite 规则直接命中。
解决:把 3.4 节的fastcgi_split_path_info配置加上,并把location /里的rewrite规则放开。如果是 Apache 环境,确认.htaccess没有被面板的 404 配置遮蔽。这一步没有捷径,我见过有人在路由文件里排查两个晚上,最后发现是伪静态规则里少写一个if (!-e $request_filename)。
5.4 队列任务一直堆积:短信不发、支付回调延迟
现象:订单能创建,但短信验证码收不到,支付回调解不了单;去 Redis 里看队列长度,任务一直在跑或一直没人消费。
原因:常见是两个。一是 queue:listen 进程没有启动,或者 supervisor 里 command 路径写错;二是 .env 里的 Redis 库号、队列通道跟后台设置不一致,任务被塞进另外一个队列通道。
解决:先在命令行手动跑一次监听,看能否消费:
php think queue:listen --tries=3 --queue=crmeb手动运行能看到实时输出,如果任务进来后立即报请求外呼失败,就往日志里看。如果手动跑没问题,那就是 supervisor 配置问题。检查 supervisor 里directory是否指向项目根目录,command是否用了绝对路径,进程用户是否为 www。若队列任务进的是默认队列而不是 crmeb 通道,去后台设置里核对消息队列配置,改完之后按 4.1 清缓存,再重启 supervisor。
5.5 上传图片成功但访问 404,或图片乱码
现象:商品图上传后,后台列表能看到缩略图,但点击原图 404;有时图片不是 404,而是浏览器提示“文件不存在”或出现一串乱码。
原因:图片文件写入了,但 Nginx 静态路径找不到,因为上传目录的真实位置可能在public/upload下面,而你的 Nginx root 指到了项目根目录;另一种是public/upload里还有一层日期目录,日期格式来自服务器时区,图片在目录里存在但 URL 路径对不上。
解决:检查 Nginx root 配置是否指向了public,这一步能解决大半;图标访问 404 但商品图正常,则检查图片域名的绑定,上传生成的 URL 如果指向了img.example.com,而该域名没有走到同一份 upload 目录,404 是必然。直接在浏览器访问文件的实际物理路径,若物理文件存在但访问 404,说明是 web 服务器指错目录;若物理不存在,那就是数据库里存的路径被裁剪或上传失败。还有一种“图片乱码”的情况,是 gd 扩展缺 webp 支持,上传的缩略图是 webp 格式而 Nginx 没有配置 mime 类型,返回的是 image/webp 之外的 Content-Type,被浏览器当成纯文本。在 Nginx 的 http 块加一行types { image/webp webp; }即可。
6. 上线前的性能与二次开发技巧
6.1 OPCache 与 Redis 缓存:一套能让商品页提速 30% 的组合
上线前我建议先把 OPCache 打开。PHP 代码在每次请求都要重新编译一遍,OPCache 可以把编译结果放进共享内存,商品页压力大的时候收益非常明显。在 php.ini 里:
opcache.enable=1 opcache.memory_consumption=128 opcache.validate_timestamps=0validate_timestamps=0是我故意关掉的:上线后你不会频繁改 PHP 文件,但每次改动都要手动清 OPCache,否则代码不变;如果还在持续二开,就保留默认 60 秒的 timestamp 校验。配合后台的 Redis 缓存,把商品详情、系统配置缓存到 Redis,能撑住比文件缓存高得多的并发。
6.2 从安装包目录结构找二开入口
二次开发时不要从头设计,先看现有的控制器和模型目录。常见包结构里,app/api是用户端接口、app/admin是平台管理端、app/merchant是商户端,对应关系一眼就能看出来。我要改“商户结算”逻辑时,先沿merchant目录找结算控制器和数据表,而不是在平台上新建一套流程。改之前先看数据库迁移文件或 SQL 里的字段,很多业务逻辑是写死在 SQL 注释里的。
我自己的习惯是每改动一个文件就记录在本地 git,不要在生产机上直接编辑;多用php think clear验证配置改动,而不是反复猜测。这套多商户包能撑到多少并发,取决于你部署时有没有把队列、缓存、权限三件事做对。希望帮到你。
本文还有配套的精品资源,点击获取