最佳方式不是“暴力删文件”而是“先盘点依赖 -做白名单编译 -扩展分层打包 -自动验收回归”。forshortcuts 这样才能又轻量、又不把业务打挂。────────────────────────────────────────────────────────────────────────────────────── --- 给你一套可直接落地的完整方案大白话 完整脚本模板。1)先明白“剥离什么” 你要剥离的是两类1. 第三方库依赖openssl/curl/icu/libxml2 等2. PHP 扩展依赖gd/intl/snmp/ldap/imap/pgsql... 目标 - 减少体积 - 减少漏洞面 - 提高启动和发布效率 - 保证业务不受影响 ---2)最佳策略四步走 第一步盘点实际用量别靠猜 - 扫代码里函数/类调用 - 扫运行时扩展加载 - 扫二进制动态库依赖ldd 第二步白名单编译 - 只保留必须扩展 - 其他全部关掉 第三步扩展分层 - 核心包必须扩展 - 可选包少量业务扩展单独 so 包按需装 第四步自动验收 - 模块校验 - 冒烟测试 - 性能对比 - 回滚包保留 ---3)完整脚本1代码静态扫描推断扩展使用 文件scan_extension_usage.php?php declare(strict_types1);$root$argv[1]?? getcwd();if(!is_dir($root)){fwrite(STDERR,invalid path: {$root}\n);exit(1);}$rules[curl_curl,mysqli_mysqli,PDOpdo,imagecreategd,imagickimagick,mb_mbstring,intlintl,openssl_openssl,simplexml_xml,SoapClientsoap,ldap_ldap,snmp_snmp,imap_imap,zip_zip,pcntl_pcntl,redisredis,];$hits[];$files0;$itnew RecursiveIteratorIterator(new RecursiveDirectoryIterator($root, FilesystemIterator::SKIP_DOTS));foreach($itas$f){if(!$f-isFile())continue;$path$f-getPathname();if(!preg_match(/\.(php|phtml|inc)$/i,$path))continue;$files;$contentfile_get_contents($path);if($contentfalse)continue;foreach($rulesas$needle$ext){if(stripos($content,$needle)!false){$hits[$ext]($hits[$ext]??0)1;}}}ksort($hits);echoScanned files: {$files}\n;echoPossible extension usage:\n;foreach($hitsas$ext$count){echostr_pad($ext,14). : {$count}\n;}---4)完整脚本2轻量化编译白名单 文件build_php_lite.sh#!/usr/bin/env bashset-euopipefailPHP_SRC${1:-}PREFIX${2:-/opt/php-lite}if[[-z${PHP_SRC}||!-d${PHP_SRC}]];thenechoUsage:$0/path/to/php-src [/install/prefix]exit1ficd${PHP_SRC}./buildconf--force# 只开核心能力其他默认不带./configure\--prefix${PREFIX}\--enable-cli\--enable-fpm\--disable-cgi\--enable-opcache\--enable-mbstring\--with-openssl\--with-zlib\--with-curl\--with-mysqli\--with-pdo-mysql\--enable-sockets\--without-pear\--disable-phpdbgmake-j$(nproc)makeinstallechoInstalled to${PREFIX}${PREFIX}/bin/php-v${PREFIX}/bin/php-m---5)完整脚本3依赖剥离检查动态库 文件check_runtime_deps.sh#!/usr/bin/env bashset-euopipefailPHP_BIN${1:-/opt/php-lite/bin/php}if[[!-x${PHP_BIN}]];thenechophp binary not found:${PHP_BIN}exit1fiecho php binary deps ldd${PHP_BIN}|sortechoecho extension deps EXT_DIR$(${PHP_BIN}-i|awk-F /^extension_dir/ {print $2}|xargs)if[[-d${EXT_DIR}]];thenforsoin${EXT_DIR}/*.so;do[[-e$so]]||continueecho---$(basename$so)---ldd$so|sortdonefi---6)完整脚本4验收与防误删 文件verify_php_lite.sh#!/usr/bin/env bashset-euopipefailPHP_BIN${1:-/opt/php-lite/bin/php}required(opensslcurlmbstring mysqli pdo_mysql zlib opcache)forbidden(snmp imap ldap odbc pgsql pdo_pgsql soap)echo Required forextin${required[]};doif${PHP_BIN}-m|grep-qi^${ext}$;thenecho[OK]${ext}elseecho[FAIL] missing${ext}exit1fidoneechoecho Forbidden forextin${forbidden[]};doif${PHP_BIN}-m|grep-qi^${ext}$;thenecho[FAIL] should be removed:${ext}exit2elseecho[OK] not loaded:${ext}fidoneechoecho Smoke ${PHP_BIN}-recho ok\n;echoverify passed---7)扩展轻量化“分层打包”建议 - php-corecli/fpm 核心扩展 - php-ext-dbpgsql/sqlite 等数据库可选 - php-ext-legacysoap/ldap/snmp 旧业务专用 - php-ext-debugxdebug生产默认不装 这样业务机只装自己需要的层最省。 ---8)最容易踩坑的点1. 一刀切关 intl多语言/金额日期格式全错2. 关 openssl/curl支付和第三方 API 全挂3. 只看功能通过不看 P95/P994. 没保留“标准全量包”导致回滚困难 --- 最后一句收住 第三方依赖剥离与扩展轻量化的最优解是“白名单编译 分层扩展包 自动验收 可回滚双版本”不是手工乱裁剪。