




PHP无法真正编译为EXE,所谓打包实为将解释器、脚本及依赖库封装成自解压容器;主流方案是ExeOutput for PHP(商业、Windows)和PHP Desktop(开源、跨平台),需手动处理扩展依赖、路径适配与运行时限制。
PHP 是解释型语言,运行依赖 php.exe(或 php-cgi.exe)和扩展库,没有官方“编译为 Windows 可执行文件”的能力。所谓“PHP 打包成 EXE”,本质是把 PHP 解释器、你的脚本、依赖的 .dll 和启动逻辑打包进一个自解压/自运行容器,不是真正意义上的编译。
目前较稳定、仍在维护的方案只有两个:
.php 文件和资源打包进单个 .exe,运行时自动解压到临时目录并调用内嵌 php-cgi.exe 启动内置服务器;www/ 目录,修改 phpdesktop-chrome\settings.json 指向入口 index.php。注意:BoxedApp Packer、PPM 等老工具已多年未更新,对 PHP 8+ 支持极差,容易触发杀毒软件误报或启动失败。
即使使用 ExeOutput,也不能默认带上所有扩展。以下几类必须手动勾选或验证:
mysqli 或 pdo_mysql,得确保 libmysql.dll(或 php_mysqli.dll)被包含,并且 MySQL 客户端库版本与 PHP 编译时匹配;openssl 需确认 ssleay32.dll 和 libeay32.dll(PHP 7.4 及以前)或 libssl-1_1.dll/libcrypto-1_1.dll(PHP 8.0+)一并打包;php_pdo_sqlite.dll 和 php_sqlite3.dll;curl 时,若提示 Unable to load dynamic library 'php_curl.dll',大概率是缺少 libcurl.dll 或其依赖的 libssh2.dll、nghttp2.dll。建议在打包前,用命令行运行一次:
php -m | findstr -i "mysqli curl openssl sqlite"确认扩展已加载,再对照工具的扩展列表做勾选。
打包后的 EXE 运行环境和原始 PHP CLI 截然不同:
__DIR__ 和 getcwd() 指向的是临时解压目录(如 C:\Users\XXX\AppData\Local\Temp\XXXXXX\),不是 EXE 所在目录 —— 必须用 dirname($_SERVER['SCRIPT_FILENAME']) 或 realpath(getenv('APPDATA') . '/YourApp/') 存放用户数据;exec()、shell_exec() 调用外部程序(除非你把对应 .exe 也打进包里,并用绝对路径调用);.htaccess)完全无效,路由必须由 PHP 自己处理(如判断 $_SERVER['REQUEST_URI']);最常被忽略的一点:调试困难。EXE 内部错误不会直接输出,
得在设置中开启日志(如 ExeOutput 的 Log errors to file),或改用 error_log() 写入指定路径排查。