PHP 类型松散致运行时错误难排查、内存与启动性能差、异步生态碎片化、DevOps 流程冗重,演进需手动解决多层耦合。
PHP 默认是弱类型,变量类型在运行时才确定,== 比较常引发隐式转换问题,比如 "0" == false 返回 true,而 "0" === false 才是预期的 false。项目规模变大后,这类逻辑错误往往要到接口返回异常数据或前端报错才暴露。
declare(strict_types=1) 只能
__call、call_user_func)支持有限,误报/漏报多典型 Laravel 应用在 FPM 模式下,单个请求常消耗 20–40MB 内存,冷启动耗时明显高于 Go 或 Node.js 的轻量 HTTP 服务。这不是框架写得差,而是 PHP 的执行模型决定的:每次请求都要重新加载全部类、解析全部配置、重建容器实例。
PHP 原生不支持 async/await 语法(直到 8.1 才有 fibers,但不是为 I/O 设计),Swoole、Amphp、ReactPHP 各自实现事件循环,彼此不兼容。想用异步 MySQL 查询?得选对扩展版本,再配对对应的 PDO 封装层。
swoole_mysql 和 mysqli 不共用连接池,切换成本高;amphp/mysql 要求所有依赖都适配 Promise,现实里很难做到coroutine_id 和 trace_id 容易断掉PHP 应用通常靠源码 + composer install 构建,不像 Go 编译出单二进制、Rust Cargo 自带 artifact 管理。Docker 镜像里既要装 PHP 运行时,又要装扩展(gd、redis、opcache),还要处理 php.ini 多环境差异。
composer.lock 不能锁定扩展版本,ext-redis 从 5.x 升到 6.x 可能破坏序列化逻辑,却不会在 composer update 时报错composer install --no-dev 仍需下载全部依赖包,比 Go 的 go build 慢数倍,尤其在低带宽 CI 环境下明显真正棘手的从来不是“PHP 能不能做”,而是当业务需要横向扩展、低延迟响应、多人高频协同时,那些隐藏在 php.ini、composer.json 和 dockerfile 里的耦合点,会突然变成瓶颈。它不拒绝演进,但每一步都得亲手拧螺丝。