两套体系完整讲透。全程大白话,所有代码可直接用,数据库/语法转换全部用官方自带工具(达梦 DTS、金仓 KDTS、Babel、PostCSS),不自研轮子。---第一部分:PHP 存量系统信创迁移方法论与踩坑全解 一、先搞懂信创迁移到底在迁什么 大白话:你原来的 PHP 系统跑在 Intel/AMD 的 x86 服务器CentOSMySQL/OracleApache/Nginx 上。信创就是把这一整套换成国产的:┌────────────┬───────────────┬─────────────────────────────────────────────────────┐ │ 层级 │ 原来(海外)│ 信创(国产替换)│ ├────────────┼───────────────┼─────────────────────────────────────────────────────┤ │ CPU │ Intel x86 │ 鲲鹏/飞腾(ARM64)、海光/兆芯(x86)、龙芯(LoongArch)│ ├────────────┼───────────────┼─────────────────────────────────────────────────────┤ │ 操作系统 │ CentOS/RedHat │ 麒麟 Kylin V10、统信 UOS │ ├────────────┼───────────────┼─────────────────────────────────────────────────────┤ │ 数据库 │ MySQL/Oracle │ 达梦 DM8、人大金仓 KingbaseES、OceanBase、openGauss │ ├────────────┼───────────────┼─────────────────────────────────────────────────────┤ │ Web 中间件 │ Apache/Nginx │ 东方通 TongWeb、Nginx(国产编译版可继续用)│ ├────────────┼───────────────┼─────────────────────────────────────────────────────┤ │ 浏览器 │ Chrome/Edge │ 奇安信、360、红莲花(都是 Chromium 内核)│ └────────────┴───────────────┴─────────────────────────────────────────────────────┘ 最大的坑就一句话:CPU 从 x86 变成了 ARM64,字节序和指令集变了,PHP 本身没问题(开源能重编),但你装的那些扩展(swoole、redis、各种.so)很多没有 ARM 版,要重新编译。---二、完整迁移流程(7步法)第1步 资产盘点 → 第2步 兼容性评估 → 第3步 环境搭建(ARM国产OS)→ 第4步 PHP及扩展重编译 → 第5步 数据库迁移(用官方工具)→ 第6步 代码SQL方言改造 → 第7步 回归测试性能压测 第1步:资产盘点(别上来就动手)先把家底摸清楚。用这个脚本一次性扫出你系统依赖了什么:#!/bin/bash # 文件名你自己存,我这里只给代码:asset_scan.sh # 作用:盘点 PHP 版本、所有扩展、用了哪些数据库函数、有没有写死 x86 的东西 echo 1. PHP 版本 php-v echo 2. 已加载扩展(重点看哪些是第三方.so) php-m echo 3. 扩展物理文件位置(看有没有现成ARM版) php-i|grep extension_dir ls-lh $(php-config--extension-dir2/dev/null||php-i|grep^extension_dir|awk{print $3})echo 4. 代码里用了哪些危险的数据库特有写法 #mysql_*老函数(PHP7已删)、Oracle的OCI、SQL方言grep-rnmysql_query\|mysql_connect\|mysqli_\|oci_\|-query(--include*.php.|head-50echo 5. 代码里有没有写死的本地命令/路径(ARM下可能没有) grep-rnexec(\|shell_exec(\|system(\|/usr/bin/\|\.exe--include*.php.|head-50echo 6. composer 依赖里有没有带C扩展的包 cat composer.json2/dev/null|grep-iext-盘点输出三张清单:1.PHP 扩展清单(哪些要重编)2.SQL 写法清单(哪些方言要改)3.系统调用清单(exec 调的命令 ARM 上有没有)---第2步:兼容性评估(判断哪些会爆雷)按这个表自查,这是90%的坑所在:┌────────────────────────────┬──────────────────────────────────────┬──────────────────────────────────────────┐ │ 风险点 │ 为什么会坑 │ 怎么处理 │ ├────────────────────────────┼──────────────────────────────────────┼──────────────────────────────────────────┤ │ swoole/swow │ 协程库深度依赖底层,早期版本没 ARM 包 │ 用 swoole5.x,官方已支持 ARM64,重编即可 │ ├────────────────────────────┼──────────────────────────────────────┼──────────────────────────────────────────┤ │ php-redis/mongodb 等.so │ 二进制只编了 x86 │ 用 pecl install 在 ARM 机器上现编 │ ├────────────────────────────┼──────────────────────────────────────┼──────────────────────────────────────────┤ │ mysql_ 老函数*│ PHP7 已彻底删除 │ 全部换成PDO(顺便为换库做准备)│ ├────────────────────────────┼──────────────────────────────────────┼──────────────────────────────────────────┤ │ Oracle OCI8 │ 达梦/金仓没有 OCI 接口 │ 换成 PDO,SQL 方言改造 │ ├────────────────────────────┼──────────────────────────────────────┼──────────────────────────────────────────┤ │ GD/ImageMagick │ 依赖系统图形库 │ 国产 OS 源里装 libpng/libjpeg 再编 │ ├────────────────────────────┼──────────────────────────────────────┼──────────────────────────────────────────┤ │ 写死的/usr/bin/x86_64...│ ARM 路径不一样 │ 改成动态查找 which │ ├────────────────────────────┼──────────────────────────────────────┼──────────────────────────────────────────┤ │ 整数/位运算依赖32位 │ LoongArch/ARM 都是64位 LP64 │ 一般无影响,但位掩码要 review │ └────────────────────────────┴──────────────────────────────────────┴──────────────────────────────────────────┘---第3步:搭建信创环境 以最主流的 麒麟V10(ARM64)达梦 DM8 为例。 # 看清楚架构,确认是aarch64(ARM64)uname-m # 输出 aarch64 就对了 cat/etc/os-release # 确认 Kylin V10 # 麒麟用的是自己的 yum 源,先装编译 PHP 必需的基础库 sudo yum install-y gcc gcc-cmake autoconf \ libxml2-devel openssl-devel libcurl-devel \ libjpeg-turbo-devel libpng-devel freetype-devel \ oniguruma-devel sqlite-devel libzip-devel---第4步:PHP 及扩展重编译(核心)大白话:PHP 源码是跨平台的,在 ARM 机器上重新./configuremake 就能编出 ARM 版,关键是扩展也得在 ARM 机器上现编。 #编译 PHP8.3本体(ARM64)cd/usr/local/src wget https://www.php.net/distributions/php-8.3.0.tar.gztar-zxvf php-8.3.0.tar.gz cd php-8.3.0#configure不需要指定架构,编译器自动认 aarch64./configure \--prefix/usr/local/php \--with-config-file-path/usr/local/php/etc \--enable-fpm \--with-openssl \--with-curl \--enable-mbstring \--with-zlib \--enable-gd--with-jpeg--with-freetype \--with-pdo-mysql \--enable-sockets \--enable-opcache make-j$(nproc)# nproc 自动用满核数 sudo make install #用 pecl 现编扩展(它会自动针对 ARM 编)sudo/usr/local/php/bin/pecl install redis sudo/usr/local/php/bin/pecl install swoole #5.x 已原生支持ARM # 在 php.ini 里加上 echoextensionredis.so/usr/local/php/etc/php.ini echoextensionswoole.so/usr/local/php/etc/php.ini # 验证扩展真的是 ARM64 的 file/usr/local/php/lib/php/extensions/*/redis.so # 输出里要有 ARM aarch64 字样才对 踩坑提醒: - 别从 x86 机器拷 .so 过来,file 命令一查就是 x86-64,装上直接 segfault。 - swoole 一定用 5.x,4.x 老版本 ARM 下编译报错多。 --- 第 5 步:数据库迁移(重点:全部用官方自带工具,不要手写脚本搬数据) 这是你特别强调的用自带工具不自研。各家国产库都有官方图形化迁移工具,直接把 MySQL/Oracle 的表结构数据索引一键搬过去。 方案 A:迁到达梦 DM8 ——用官方 DTS(DM Data Transfer Service) 达梦自带 dts 工具,在 达梦安装目录/tool/dts 下,图形界面操作: 1. 新建迁移 →选源(MySQL)→填 MySQL 连接 2. 选目标(DMSQL)→填达梦连接 3. 勾选要迁的表 →勾迁移对象包含:表结构数据索引约束 4. 高级选项:把 对象名大小写 设为和原库一致(达梦默认大写,这是大坑!) 5. 点开始,它自动建表灌数据 命令行批量方式(适合自动化): # 达梦命令行迁移工具 dmfldr / dts_console # 达梦提供 dts 的命令行版,导出一个迁移配置 xml 后执行 cd /opt/dmdbms/tool ./dts_console /filemigrate_config.xml /logmigrate.log # migrate_config.xml 在图形界面里点保存配置就能生成,不用手写 方案 B:迁到人大金仓 KingbaseES ——用官方 KDTS 实时同步用 KFS # KDTS:全量迁移工具(金仓安装包自带,Tools/kdts 目录) # 图形界面:配置源 MySQL →目标 Kingbase →自动转换数据类型 →迁移 # 它内置了 MySQL→Kingbase的类型映射,不用你自己对照 # KFS:迁移完之后,业务还在跑,用 KFS 做增量实时同步,实现双跑不停机 # 配置好后 MySQL 的新增改删会实时同步到 Kingbase,等切换窗口一到直接切 方案 C:迁到 OceanBase ——用官方 OMS(OceanBase Migration Service) OMS 是图形化平台,功能最全: - 结构迁移 全量迁移 增量同步 反向同步(回滚保险) - MySQL 模式几乎零改造(OceanBase 高度兼容 MySQL 协议) 若你原库是 MySQL,迁 OceanBase 最省事,SQL 基本不用改。 选型大白话建议: - 原来是 MySQL →优先 OceanBase(兼容 MySQL,代码几乎不改)。 - 政府/国企强制要求达梦/金仓 →用 达梦 DTS / 金仓 KDTS,但 SQL 方言要改(见第 6 步)。 - 原来是 Oracle →达梦兼容 Oracle 语法最好,用达梦,改动最小。 --- 第 6 步:代码 SQL 方言改造(改造量最大的一步) 大白话:不同数据库 SQL 写法有差异,达梦/金仓不认 MySQL 的某些语法。最优策略——用PDO 把数据库访问收口到一个地方,改一处就行,别在几百个文件里散着写 SQL。 6.1 先把所有数据库访问统一成 PDO(标准做法,最优方案) ?php // 统一数据库连接层 ——改库只改这一个文件的 DSN class Db { private static ?PDO $pdo null; public static function conn(): PDO { if (self::$pdo ! null) { return self::$pdo; } // 切换数据库就改这里的 DSN,业务代码一行不动 // 原 MySQL: // $dsn mysql:host127.0.0.1;port3306;dbnameapp;charsetutf8mb4; // 达梦 DM8(走官方 PDO_DM 驱动 或 ODBC): // $dsn dm:host127.0.0.1;port5236; // 人大金仓 / openGauss(兼容 PostgreSQL 协议,用 pdo_pgsql): // $dsn pgsql:host127.0.0.1;port54321;dbnameapp; // OceanBase(兼容 MySQL,继续用 pdo_mysql): $dsn mysql:host127.0.0.1;port2883;dbnameapp;charsetutf8mb4; self::$pdo new PDO($dsn, username, password, [ PDO::ATTR_ERRMODE PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE PDO::FETCH_ASSOC, PDO::ATTR_EMULATE_PREPARES false, // 用真预处理,防注入也更兼容 ]); return self::$pdo; } } 业务里全部用预处理,杜绝 SQL 注入,也最容易跨库: ?php // 所有查询都走这个标准姿势 $stmt Db::conn()-prepare(SELECT id, name FROM users WHERE age ? AND city ?); $stmt-execute([18, 北京]); $rows $stmt-fetchAll(); 6.2 常见 SQL 方言差异对照表(达梦/金仓踩坑清单) ┌──────────────────────────────────┬─────────────────────────────────┬───────────────────────────────────────────┐ │ MySQL 写法 │ 达梦 / 金仓 不认 │ 跨库正确写法 │ ├──────────────────────────────────┼─────────────────────────────────┼───────────────────────────────────────────┤ │ column 反引号 │ 不支持反引号 │ 用双引号 column 或不加引号 │ ├──────────────────────────────────┼─────────────────────────────────┼───────────────────────────────────────────┤ │ LIMIT 10 OFFSET 20 │ 达梦用 │ 用标准 OFFSET 20 ROWS FETCH NEXT 10 ROWS │ │ │ LIMIT,金仓支持但语法略不同 │ ONLY │ ├──────────────────────────────────┼─────────────────────────────────┼───────────────────────────────────────────┤ │ IFNULL(a,b) │ 不支持 │ 用标准 COALESCE(a,b) │ ├──────────────────────────────────┼─────────────────────────────────┼───────────────────────────────────────────┤ │ NOW() / CURDATE() │ 部分不支持 │ 达梦用 SYSDATE,金仓用 CURRENT_TIMESTAMP │ ├──────────────────────────────────┼─────────────────────────────────┼───────────────────────────────────────────┤ │ GROUP_CONCAT() │ 不支持 │ 达梦 WM_CONCAT,金仓 STRING_AGG │ ├──────────────────────────────────┼─────────────────────────────────┼───────────────────────────────────────────┤ │ INSERT ... ON DUPLICATE KEY │ 不支持 │ 用标准 MERGE INTO │ │ UPDATE │ │ │ ├──────────────────────────────────┼─────────────────────────────────┼───────────────────────────────────────────┤ │ auto_increment │ 写法不同 │ 达梦/金仓用序列 SEQUENCE │ ├──────────────────────────────────┼─────────────────────────────────┼───────────────────────────────────────────┤ │ 表名/字段名大小写不敏感 │ 达梦默认全大写 │ 迁移时统一,或代码里全大写 │ └──────────────────────────────────┴─────────────────────────────────┴───────────────────────────────────────────┘ 最优做法:用查询构造器 / ORM 屏蔽方言,别手写裸 SQL。 推荐用 Laravel 的 Eloquent / 查询构造器 或 Doctrine DBAL,它们内置 了各数据库的语法转换器(Grammar),你写一份代码,它自动翻译成对应数据库的方言——这就是你要的用自带语法转换工具不自研: ?php // 用 Laravel 查询构造器,跨库零改造(它内部按驱动自动生成对应方言SQL) use Illuminate\Database\Capsule\Manager as Capsule; $capsule new Capsule; $capsule-addConnection([ driver pgsql, // 金仓/openGauss 用 pgsql;OceanBase 用 mysql;达梦用社区dm驱动 host 127.0.0.1, port 54321, database app, username user, password pwd, ]); $capsule-setAsGlobal(); $capsule-bootEloquent(); // 业务代码完全不感知底层是什么库,框架自动翻译方言 $users Capsule::table(users) -where(age, , 18) -orderBy(id) -limit(10)-offset(20) // 框架自动转成各库正确的分页语法 -get(); --- 第 7 步:回归测试 性能压测 # 1. 功能回归:跑你原有的 PHPUnit 测试套件 ./vendor/bin/phpunit # 2. 接口回归:用 ab 压测对比 x86 和 ARM 下的接口表现 ab -n 5000 -c 100 http://127.0.0.1/api/users # 3. 重点压数据库:达梦/金仓的执行计划和 MySQL 不同,慢SQL要重新优化 # 达梦看执行计划: # EXPLAIN SELECT ... ; 然后对慢查询补索引 ARM 性能踩坑: ARM 单核主频可能低于 Intel,但核多。PHP-FPM 的 pm.max_children 要按 ARM 核数调大,把多核吃满,整体吞吐不输 x86。 --- 三、PHP 信创迁移踩坑 Top 10 速查 1. 从 x86 拷 .so 到 ARM →必崩,所有扩展 ARM 机现编。 2. 达梦默认大写表名 →迁移和代码大小写不一致,查不到数据。迁移时统一。 3. mysql_ 老函数* →PHP7 已删,全换 PDO。 4. 反引号 →达梦/金仓不认,换双引号。 5. 自增主键 →国产库要建 SEQUENCE,迁移工具能自动转,别手建漏了。 6. 中文乱码 →字符集统一 UTF-8,达梦建库时指定 CHARSETUTF-8。 7. swoole 4.x →ARM 编译报错,升 5.x。 8. exec 调系统命令 →ARM 上命令路径/参数不同,用 which 动态找。 9. 时间函数 NOW()/SYSDATE →方言不同,用 ORM 或 COALESCE 类标准函数。 10. 不做增量同步直接停机切 →数据丢失风险,用 KFS/OMS 做双跑同步再切。 --- --- 第二部分:国产浏览器与 PHP 前端交互兼容性适配体系 一、先搞懂国产浏览器到底是什么 大白话:国产浏览器(奇安信、360 安全浏览器、红莲花、UOS 浏览器)绝大多数是基于 Chromium 内核改的,所以现代 JS/CSS 基本都支持。真正的坑是两个: 1. 双核浏览器:360、搜狗这类有极速模式(Chromium)和兼容模式(IE 内核 Trident)两套内核。政府老系统常被强制用 IE 兼容模式,那就是 IE8/IE9 级别的远古环境,你的 ES6、fetch、flex 全跪。 2. Chromium 版本偏老:有些国产浏览器内核停留在 Chromium 8x、9x,最新的 ES2022 语法、?. 可选链可能不支持。 核心策略一句话:用 Babel 把新 JS 翻译成老 JS,用 PostCSSAutoprefixer 把新 CSS 翻译成老 CSS,用 core-js 把缺失的 API 补上。这些全是业界标准工具,绝不自研。 --- 二、完整适配流程 第1步 探测目标浏览器内核与版本 → 第2步 定 browserslist 目标 → 第3步 Babel转译JScore-js补丁 → 第4步 PostCSS转译CSS → 第5步 PHP后端按UA下发对应资源 → 第6步 IE兼容模式兜底处理 → 第7步 真机回归测试 --- 第 1 步:探测目标浏览器(先知道敌人是谁) 后端用 PHP 解析 UA,前端用 JS 探测能力。先做个探测页跑一遍: ?php // 后端探测:解析 User-Agent,判断是哪个国产浏览器、什么内核 function detectBrowser(string $ua): array { $result [name unknown, engine unknown, mode modern]; // 国产浏览器特征(它们 UA 里都带各自标识) if (stripos($ua, QihooBrowser) ! false || stripos($ua, QiHoo) ! false) { $result[name] 奇安信/360; } elseif (stripos($ua, UOSBrowser) ! false) { $result[name] 统信UOS浏览器; } elseif (stripos($ua, Hongmeng) ! false || stripos($ua, HarmonyOS) ! false) { $result[name] 鸿蒙; } // 关键:判断是不是落到了 IE 兼容模式(TridentIE内核) if (stripos($ua, Trident) ! false || stripos($ua, MSIE) ! false) { $result[engine] Trident(IE内核); $result[mode] legacy; // 远古模式,要兜底! } elseif (stripos($ua, Chrome) ! false) { // 抓出 Chromium 版本号,判断老不老 preg_match(/Chrome\/(\d)/, $ua, $m); $ver (int)($m[1] ?? 0); $result[engine] Chromium $ver; $result[mode] $ver 80 ? old-chromium : modern; } return $result; } // 用法 $info detectBrowser($_SERVER[HTTP_USER_AGENT] ?? ); // $info[mode] 决定后面下发哪套前端资源 --- 第 2 步:用 browserslist 声明你要兼容到多老 大白话:browserslist 是一个配置文件,你写明我要支持到 IE9、Chrome 49,后面所有工具(Babel、PostCSS)都读它,自动决定翻译到什么程度。这是整个体系的总开关。 // package.json 里加一段(这就是 browserslist 配置,业界标准,所有工具都认它) { browserslist: [ 0.5%, last 2 versions, Chrome 49, ie 9, Firefox ESR ] } 如果确认要兼容 IE 兼容模式(政府场景),就把 ie 9 写进去,Babel 会自动转到 ES5。 --- 第 3 步:Babel 转译 JS core-js 补 API(最关键) 大白话:你写 ES6 的现代 JS(箭头函数、const、async/await、可选链),Babel 自动翻译成老浏览器能跑的 ES5。语法它翻译,新 API(Promise、fetch、Array.includes)它用 core-js 补丁补上。全自动,你只管写现代代码。 # 安装 Babel 全家桶 core-js(都是官方标准库,不自研) npm install --save-dev babel/core babel/cli babel/preset-env npm install core-js3 // babel.config.js ——Babel 配置,核心是 preset-env corejs module.exports { presets: [ [babel/preset-env, { // 不写 targets,它自动读 package.json 里的 browserslist useBuiltIns: usage, // 关键:只按你代码实际用到的API来打补丁,体积最小 corejs: 3, // 用 core-js3 提供 Promise/fetch等垫片 }], ], }; # 执行转译:把现代源码 src/ 翻译成老浏览器能跑的 dist/ npx babel src --out-dir dist 效果对比(Babel 自动帮你做的翻译): // 你写的现代代码(src/app.js) const getUser async (id) { const res await fetch(/api/user?id${id}); const data await res.json(); return data?.name ?? 匿名; // 可选链 空值合并 }; // Babel 自动翻译成 ES5(dist/app.js),IE 也能跑(配合core-js的Promise/fetch补丁) // 你完全不用手写这些兼容代码,Babel 全自动生成 踩坑提醒: 一定要装 core-js 并设 useBuiltIns: usage。光转语法不补 API,IE 里 Promise is not defined 照样崩。 --- 第 4 步:PostCSS 转译 CSS Autoprefixer 自动加前缀 大白话:CSS 也一样。你写标准的 flex、grid,Autoprefixer 自动加 -webkit-、-ms- 前缀让老内核认识。同样读 browserslist,全自动。 npm install --save-dev postcss postcss-cli autoprefixer postcss-preset-env // postcss.config.js module.exports { plugins: [ // postcss-preset-env:把现代CSS(嵌套、自定义属性)翻译成老CSS require(postcss-preset-env)({ stage: 2 }), // autoprefixer:自动加浏览器前缀,也是读 browserslist require(autoprefixer), ], }; npx postcss src/style.css -o dist/style.css 效果: /* 你写的现代 CSS */.box{display:flex;user-select:none;}/* Autoprefixer 自动加前缀后(老国产内核/IE兼容模式能认) */.box{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-user-select:none;-ms-user-select:none;user-select:none;}最优整合方案:别手动跑 babel/postcss 命令,用 Vite 打包,它内部集成了这一整套。// vite.config.js ——最优:一个配置全搞定,生产构建自动 BabelPostCSSlegacy 兜底import{defineConfig}fromvite;importlegacyfromvitejs/plugin-legacy;exportdefaultdefineConfig({plugins:[// 这个官方插件自动为老浏览器生成 ES5 版本 注入 polyfill,IE11也能跑legacy({targets:[ie 11,Chrome 49],additionalLegacyPolyfills:[regenerator-runtime/runtime],}),],});vitejs/plugin-legacy 是最省事的——它会自动产出现代版和老旧版两套bundle,现代浏览器加载现代版,老国产浏览器自动降级加载 ES5 版,完全自动。---第5步:PHP 后端按浏览器下发对应资源(差异化下发)大白话:用第1步探测的结果,给现代浏览器发现代 bundle,给 IE 兼容模式发 ES5 兜底版。这叫自适应下发。?php// PHP 模板里,根据探测结果决定加载哪套前端资源$infodetectBrowser($_SERVER[HTTP_USER_AGENT]??);?!DOCTYPE htmlhtmlheadmeta charsetutf-8!--关键!强制360/搜狗双核浏览器用极速模式(Chromium)而不是IE兼容模式--meta namerenderercontentwebkit!--强制 IE 用最高级内核,别用兼容视图--meta http-equivX-UA-CompatiblecontentIEedge,chrome1?phpif($info[mode]legacy):?!--落到IE内核了:加载 ES5 兜底版提示升级--script nomodule src/dist/legacy/app.es5.js/scriptlink relstylesheethref/dist/legacy/style.css?phpelse:?!--现代内核:加载现代版,用 typemodule让老浏览器自动忽略--script typemodulesrc/dist/modern/app.js/scriptlink relstylesheethref/dist/modern/style.css?php endif;?/headbodydiv idapp/div/body/htmlmeta namerenderercontentwebkit这行是国产双核浏览器的命脉——它告诉360/搜狗:用 Chromium 极速内核渲染我,别用 IE 兼容内核。加了这行,90%的国产浏览器兼容问题直接消失。---第6步:IE 兼容模式兜底(实在躲不掉的远古环境)如果客户死活要求在 IE 兼容模式下能用,加这层兜底:!--在head最前面用条件注释引入IE专用polyfill(只有IE认条件注释)--!--[iflte IE9]script srchttps://polyfill.io/v3/polyfill.min.js?featureses6,fetch,Promise/script![endif]--// 前端能力探测降级:发现是远古环境就给个友好提示,引导用极速模式if(!window.fetch||!window.Promise){document.getElementById(app).innerHTMLdiv stylepadding:40px;text-align:center;检测到您正在使用兼容(IE)模式,请点击地址栏右侧的b闪电图标/b切换到极速模式以获得最佳体验。/div;}---第7步:真机回归测试 大白话:国产浏览器有自己的怪癖,模拟器不准,必须真机测。 重点测这几样:// 兼容性自检脚本,在目标国产浏览器里跑一遍,看哪些挂了constchecks{ES6箭头函数:((){try{eval(((){}));returntrue;}catch{returnfalse;}})(),Promise:typeof Promise!undefined,fetch:typeof fetch!undefined,Flexbox:CSS.supportsCSS.supports(display,flex),Grid:CSS.supportsCSS.supports(display,grid),CSS变量:CSS.supportsCSS.supports(--a,0),};console.table(checks);// 哪个是 false 就针对性补 polyfill测试矩阵建议覆盖:奇安信浏览器、360(极速兼容双模式)、统信 UOS 浏览器、红莲花 ×麒麟/UOS 操作系统。---三、前端兼容踩坑 Top8速查1.双核浏览器默认进了 IE 兼容模式 →加meta namerenderercontentwebkit强制极速内核。2.只转语法没补 API →装 core-js,Promise isnotdefined 才不会崩。3.手写兼容代码 →别!用 BabelAutoprefixer 自动转,自研必出错。4.国产浏览器 Chromium 版本偏老 →browserslist 里目标定低一点,如 Chrome49。5.字体问题 →国产 OS 默认无微软雅黑,CSS 里 font-family 加思源黑体,Noto Sans CJK兜底。6.HTTPS 国密证书 →国产浏览器可能要求 SM2 国密证书,Nginx 要配国密版。7.meta charset没写或写晚 →中文乱码,必须放head第一行。8.fetch 跨域 →老国产内核 CORS 实现有差异,后端 PHP 记得发全 Access-Control-Allow-*头。---四、两套体系的最优工具链总结 ┌─────────────────┬─────────────────────────────────────────────────────┐ │ 任务 │ 最优工具(全是官方/业界标准,不自研)│ ├─────────────────┼─────────────────────────────────────────────────────┤ │ MySQL→达梦迁移 │ 达梦官方 DTS │ ├─────────────────┼─────────────────────────────────────────────────────┤ │ MySQL→金仓迁移 │ 金仓KDTS(全量)KFS(增量同步)│ ├─────────────────┼─────────────────────────────────────────────────────┤ │ MySQL→OceanBase│ OMS 迁移服务(最省事)│ ├─────────────────┼─────────────────────────────────────────────────────┤ │ Oracle→国产库 │ 达梦(Oracle 兼容最好)│ ├─────────────────┼─────────────────────────────────────────────────────┤ │ PHP 数据库跨库 │ PDOLaravel查询构造器/DoctrineDBAL(自动方言转换)│ ├─────────────────┼─────────────────────────────────────────────────────┤ │ PHP 扩展 ARM 化 │ pecl 现编(不要拷贝.so)│ ├─────────────────┼─────────────────────────────────────────────────────┤ │ JS 语法转译 │ Babel babel/preset-env │ ├─────────────────┼─────────────────────────────────────────────────────┤ │ JS API 补丁 │ core-js3│ ├─────────────────┼─────────────────────────────────────────────────────┤ │ CSS 转译加前缀 │ PostCSSAutoprefixerpostcss-preset-env │ ├─────────────────┼─────────────────────────────────────────────────────┤ │ 一键打包降级 │ Vitevitejs/plugin-legacy │ └─────────────────┴─────────────────────────────────────────────────────┘---需要我针对你的具体场景再往下钻吗?比如:-你现在用的是 MySQL 还是 Oracle,目标是 达梦还是金仓?我给你专门那条线的完整迁移脚本。-你的 PHP 框架是 Laravel/ThinkPHP/原生?改造方式不一样,我给对应的改法。-国产浏览器具体是哪几款?我帮你定精确的 browserslist。 告诉我环境,我直接给你贴合实际的完整代码。