简介:Modoer多功能点评系统 v1.2.0 Build 090806 UTF-8源码包,是一套基于PHP的电商点评平台,适合想学习开源电商系统搭建、二次开发点评类站点的初学者与开发者。通过商品点评、购买决策等核心功能,可直观理解B2B/B2C等模式下的业务流转与交互设计。压缩包共897个文件,约1.63MB,其中433个PHP文件构架主要业务逻辑,148个HTM与80个HTML提供页面模板,150个GIF、JS/CSS等完善前端表现与交互,15个SQL文件用于数据库初始化,另含少量HTC、SWF及配置文件。资源整体轻量、结构清晰,便于本地部署与源码研读。已有70人学习下载。Modoer以UTF-8编码发布,对中文多语言环境友好,部署时注意将其中老旧PHP函数适配至7.2以上版本。读者可获得完整站点源码、数据库脚本与前端样式,适合据此搭建原型、梳理电商系统表结构及二次开发练习。
1. Modoer v1.2.0 点评系统:老代码里的 UTF-8 部署边界
Modoer v1.2.0 Build 090806 这个包我接过不止一次,它是 2009 年的 UTF-8 版本,典型的 PHP 老牌点评建站程序。装它的人通常有明确目的:要么在电商站旁边挂一套本地商户点评,要么复现老点评站做历史项目存档。但它大概率让你在字符集上卡壳——那个年代 UTF-8 在 PHP 生态里并没有像今天这样默认铺开,文件名、数据库连接、HTTP 头都可能是 GBK 或者漏配,于是同一个页面,有人白屏,有人乱码,有人说好好的没毛病。这个版本的核心能力是分类、商家、点评、会员、资讯、活动,正好覆盖点评站的基础闭环,不是单页脚本。下文按解压到部署再到改点评列表的顺序展开,每一层都尽量给到能复制的命令和参数。
2. 拆包与编码加固:三层一致才敢谈安装
Modoer 这类 UTF-8 版本最容易犯的错,是只把程序文件换成了 UTF-8 编码,却忽略了运行时的两层:数据库连接和 HTTP 输出。文件层、连接层、输出层任何一层不一致,页面上就会出现�或锟斤拷。所以我拿到包的第一件事不是解压跑安装,而是先做三层校验。
2.1 先解压再看目录结构,别急着开安装向导
压缩包是 rar 格式,Linux 下用 unrar 解压,Windows 下用 WinRAR 或 7-Zip 都行。命令如下:
mkdir -p /www/modoer && cd /www/modoer unrar e -o- modoer_utf8.rar解压后第一眼要看install/、data/、templates/三个目录是否齐全。install/是安装向导,data/通常存放配置和缓存,templates/是模板文件。如果只有入口页而缺少install/目录,说明包被裁过,需要补安装程序,而不是继续往下走。
参数说明:-o-表示遇到已存在文件时不覆盖,避免二次解压污染;解压到独立目录modoer,防止把 PHP 文件散落到站点根目录难管理。RAR 包解压后建议顺手验证一次文件数量,用find . -type f | wc -l,和包内清单对得上再继续。
2.2 文件编码检查:乱码不是最大问题,BOM 才是
Modoer 的 UTF-8 版大部分源文件本身没有 BOM,但模板文件、语言包文件在 Windows 下编辑保存时很容易被加上 BOM。BOM 是文件头多出的EF BB BF三个字节,PHP 解析器会把它们当作输出内容,导致两个典型症状:headers already sent和 session 启动失败。
检查命令:
find . -name "*.php" -exec file -bi {} \; | grep -v "utf-8" | head -20 find . -name "*.php" -exec grep -rlP "\xEF\xBB\xBF" {} \;第一条找出不是 UTF-8 的 PHP 文件,第二条直接搜 BOM 标记。若有输出,批量去除 BOM:
find . -name "*.php" -exec sed -i '1s/^\xEF\xBB\xBF//' {} \;参数说明:file -bi输出 MIME 与编码信息,grep -v "utf-8"过滤出非 UTF-8 文件;sed -i '1s/^\xEF\xBB\xBF//'只处理第一行开头,不会误删正文里的合法字节。执行后再跑一次第二条命令,直到无输出才算干净。
2.3 数据库建库与连接串:UTF-8 三层配置表
文件层通过后,看数据库。在 MySQL 里建库时就要指定字符集,否则表默认跟着服务器走,可能出现 latin1 或 gbk 存储。建库语句示例:
CREATE DATABASE IF NOT EXISTS modoer DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;然后修改 Modoer 的数据库连接配置,老包通常在data/目录下有个config.inc.php或类似命名。连接建立后补一句:
<?php // config.inc.php 片段示意,位置在 mysql_select_db 之后 mysql_query("SET NAMES 'utf8'", $conn); mysql_query("SET character_set_client=utf8", $conn); mysql_query("SET character_set_results=utf8", $conn);这句是连接层的关键,少了它,即使表和文件都是 UTF-8,查询结果也可能被 MySQL 按客户端默认字符集转换,页面上文字就成乱码。老包如果用mysql_*系列函数,PHP 5.5+ 会直接报函数不存在,后面第 3 章会讲环境选择。
这里把三层对应关系整理成一个表,排查时直接对照:
| 层级 | 位置 | 常见错误 | 正确做法 |
|---|---|---|---|
| 文件层 | PHP、模板、语言包 | 文件被存成 GBK 或带 BOM | find扫描,非 UTF-8 则iconv转码 |
| 连接层 | config 文件、SQL 连接 | 未执行SET NAMES utf8 | 连接后立即执行,确保客户端与服务器一致 |
| 输出层 | HTTP 头、HTML meta | 响应头缺 charset | header()输出,或 php.ini 设default_charset |
2.4 HTTP 输出层:浏览器默认编码可能不是 UTF-8
HTML 里写了<meta charset="utf-8">不代表响应头正确。老版 PHP 的default_charset默认是空,服务器返回头部没有Content-Type: text/html; charset=utf-8时,浏览器可能按系统区域编码解析,中文页面直接乱。在入口文件或公共包含文件里补上:
<?php // 入口文件顶部,任何输出之前 header('Content-Type: text/html; charset=utf-8');更省事的做法是在php.ini里设default_charset = "utf-8"。如果 PHP 是编译安装的,修改后要重启 PHP-FPM 或 Apache;如果用 Docker,在容器配置里注入环境变量即可。输出层漏配的典型现象是首页正常、点进栏目后乱码,因为某些页面没走公共头部。
到这里,三层一致性检查完成,才轮到跑安装向导。
3. 本地跑通 Modoer 的最小环境与安装参数
Modoer v1.2.0 的时代主流是 PHP 5.2/5.3,配 MySQL 5.x,Apache 或 Nginx。现代服务器默认安装的 PHP 8.x 直接跑这个包会报错一堆,主要原因是老代码用了mysql_*函数和全局变量式的参数传递。本地验证或开发时,建议先复刻一个接近当年的运行环境。
3.1 判断本机 PHP 版本能否直接运行
命令行执行两条检查:
php -v php -m | grep -iE 'mysql|pdo|session|gd|mbstring'如果 PHP 版本是 7.0 以下,mysql_*函数可能还能用;7.0 以上已经是mysqli或PDO的天下,老包基本跑不起来。最稳的办法是直接用 Docker 拉一个老版本镜像,下面第 5 章会给具体编排文件。先把可接受的参数整理成表:
| 环境项 | 建议值 | 说明 |
|---|---|---|
| PHP | 5.2.x ~ 5.6.x | 5.6 需要装兼容补丁;5.2/5.3 最贴近原版 |
| MySQL | 5.5 ~ 5.7 | 8.0 对老连接方式兼容性差,不建议直接用 |
| PHP 扩展 | mysql / pdo_mysql / gd / session | 模板缩略图需要 GD |
| memory_limit | 128M | 安装向导和批量点评导入时避免内存不足 |
| upload_max_filesize | 32M | 商家传图时用得上 |
3.2 安装向导与目录权限
解压后先把data/目录设为可写,否则安装向导写不了配置文件:
chmod -R 775 data chown -R www-data:www-data data # 换用你 Web 服务的运行用户然后浏览器访问http://你的域名/install/,按向导填三组信息:数据库地址、数据库名/用户名/密码、管理员账号。安装向导里如果出现字符集选项,务必选择 utf8,而不是默认的 gbk 或 latin1。安装完成后删掉或改名install/目录,这是老 PHP 系统的惯例,防止被重新安装覆盖配置。
3.3 Nginx 和 Apache 的伪静态配置
Modoer 1.2 的面包屑和商户页 URL 默认带?mod=...参数,不开启伪静态也能跑,但电商场景下点评列表页的 URL 会很长。Nginx 常见配置骨架:
server { listen 80; server_name modoer.test; root /www/modoer; index index.php; location / { try_files $uri $uri/ /index.php?$query_string; } location ~ \.php$ { include snippets/fastcgi-php.conf; fastcgi_pass unix:/run/php/php5.6-fpm.sock; } client_max_body_size 32m; }Apache 则用.htaccess开 rewrite:
RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ index.php [L]参数说明:try_files先找真实文件,找不到再交给index.php,这样点评分类页的伪静态路径能落到路由上;client_max_body_size对应图片上传,电商点评里的商家实拍图经常超过默认 2M。
4. 商户点评列表的二次开发:模板循环、聚合查询与 URL 重写
系统装通只是第一步。做电子商务场景,首页不能只挂几行最近点评,常见需求是把点评按商户聚合,算平均分,再按分类筛选。Modoer 1.2 的核心表结构围绕点评设计,二次开发时要先摸清模板标签和查询入口。
4.1 模板循环的基本套路
点评系统的模板引擎有着明显的循环结构。模板文件里常见的是{loop $list $item}开头的区块,{$item.title}输出标题,{$item.content}输出点评正文。这类标签读起来接近 PHP 原生语法,改表头、换排序都在这层。
示例,改造商户点评列表的循环:
<!-- templates/default/item_list.htm 片段示意 --> <ul class="modoer-list"> {loop $list $item} <li> <h3><a href="{$item.url}">{$item.title}</a></h3> <p class="score">综合评分:{$item.score}</p> <p class="brief">{Eval echo mb_substr($item['content'],0,60,'utf-8');}</p> </li> {/loop} </ul>逻辑说明:{loop}是模板层遍历数组;mb_substr按字符截断,不加它截英文没问题,截中文会从半个汉字处断开,页面出现乱码和破损标签。这是点评列表最常见的坑。
4.2 一个实用的点评聚合 SQL
模板能显示内容后,查询逻辑决定列表质量。按商户聚合平均分,并带上点评数量的 SQL:
SELECT s.id, s.name, AVG(r.score) AS avg_score, COUNT(r.id) AS review_count FROM modoer_shop s LEFT JOIN modoer_review r ON r.shop_id = s.id WHERE s.status = 1 GROUP BY s.id HAVING COUNT(r.id) >= 1 ORDER BY avg_score DESC, review_count DESC LIMIT 0, 20;参数说明:LEFT JOIN确保没有点评的商户也出现在结果里,HAVING COUNT(r.id) >= 1过滤掉零点评商户,让首页展示的是真正有口碑数据的店铺。执行慢的话给r.shop_id建索引:
ALTER TABLE modoer_review ADD INDEX idx_shop_id (shop_id);4.3 URL 重写与分类聚合页
伪静态规则要配合rewrite使用。Nginx 下分类页需要把index.php?mod=shop&cat_id=12映射成/shop/cat12.html:
location / { try_files $uri $uri/ /index.php?$query_string; rewrite ^/shop/cat([0-9]+)\.html$ /index.php?mod=shop&cat_id=$1 last; }Apache 对应规则:
RewriteRule ^shop/cat([0-9]+)\.html$ index.php?mod=shop&cat_id=$1 [L]这里有一个细节:很多站点对动态点评页只抓到头部的<meta charset="utf-8">,正文不进去,因为动态参数 URL 容易被视为低质量页面。做好了分类聚合页的伪静态,配合<meta name="description">输出分类下的商家摘要,页面收录质量会明显改善。模板里把这个 description 从空字符串改成当前分类名加商家数量即可,别写太长。
5. 验证 UTF-8 链路与容器化部署的注意点
部署完成后,验证字符集是否全链路一致,有三个命令最直接。
curl -sI http://localhost/ | grep -i "content-type" mysql -umodoer -p -e "SHOW VARIABLES LIKE 'character_set%';" python3 -c "from pathlib import Path; [print(p) for p in Path('.').rglob('*.php') if b'\xef\xbb\xbf' in p.read_bytes()[:3]]"第一条看 HTTP 响应头是否带charset=utf-8;第二条看 MySQL 客户端的character_set_client、character_set_results是否为 utf8;第三条扫描整站 PHP 文件有没有被重新加入 BOM。三条都通过,再刷新页面看中文点评内容,基本就是一路正常。
真机环境版本太旧不好维护时,用 Docker 固定环境是效率最高的方案。以 PHP 5.6 加 Apache 镜像为例:
FROM php:5.6-apache RUN docker-php-ext-install mysql mysqli gd RUN a2enmod rewrite COPY . /var/www/html/ COPY config/000-default.conf /etc/apache2/sites-available/构建并启动:
docker build -t modoer-local . docker run -d -p 8080:80 -e MYSQL_HOST=172.17.0.1 modoer-local参数说明:docker-php-ext-install需要镜像里带源码,mysql扩展在 PHP 5.6 下还能安装;Apache 容器默认没有启用 rewrite,a2enmod rewrite必须先执行,否则伪静态规则不生效。宿主机上的 MySQL 要开远程权限,或者直接用--link连另一个 MySQL 容器。
容器化后有一个小技巧值得保留:在php.ini里追加default_charset = "utf-8",并用php -i | grep default_charset确认已生效。这样即使某个模板忘记写header(),浏览器也能拿到正确的字符集声明。最后把首页、分类页、点评详情页和安装向导几个关键路径各访问一遍,确认无乱码、无 header 警告、无 rewrite 404,这套 Modoer 的 UTF-8 点评系统才算真正落地。
本文还有配套的精品资源,点击获取