PHP 八股题库
这份题库重点不是“纯语法”,而是面向中高级 PHP 后端岗位,尤其适合你这种长期做复杂业务系统的人。
一、PHP 面试里你要怎么定位自己
你最稳的说法是:
我的 PHP 经验不是停留在写接口,而是长期用 PHP 承接复杂业务系统,比如订阅、支付、退款、交易、后台、活动和多服务协同。
这句话很关键,因为它把 PHP 从“语言”拉到了“复杂业务承接能力”。
二、高频题
1. PHP-FPM 是什么,Nginx 和 PHP-FPM 是怎么协作的
标准回答
PHP-FPM 是 PHP 的 FastCGI 进程管理器,主要负责管理 PHP Worker 进程。Nginx 收到动态请求后,会通过 FastCGI 协议把请求转发给 PHP-FPM,再由 PHP-FPM 调起对应的 PHP 脚本执行,执行完成后把结果返回给 Nginx,再由 Nginx 返回给客户端。
你可以补的点
- Nginx 负责静态资源、连接管理和反向代理
- PHP-FPM 负责 PHP 脚本执行
- PHP-FPM 进程池可以配置:
staticdynamicondemand
项目里怎么讲
你可以说:
像后台系统、交易链路、海外业务平台这类 PHP 服务,本质上都依赖 Nginx + PHP-FPM 这种模式。线上排查时,我也会关注 FPM worker 数、慢请求、max_children 打满这些问题。
2. interface、abstract class、trait 的区别
标准回答
interface更强调规范,定义方法签名,不提供实现abstract class更强调抽象基类,可以有部分实现和属性trait更像代码复用工具,用于横向复用方法,解决单继承限制
面试更稳的说法
如果是业务约束,我更倾向用 interface; 如果是一组相关对象有公共状态和默认实现,我会用 abstract class; 如果只是复用一段公共能力,比如日志、格式化、公共工具方法,我会考虑 trait,但不会滥用。
3. include、require、include_once、require_once 区别
标准回答
include找不到文件会警告,但脚本继续执行require找不到文件会 fatal error,脚本中断_once会检查是否已经加载,避免重复引入
面试更稳的说法
现代项目里更多会走 Composer autoload,手写 include / require 的场景已经少很多,但理解它们对历史项目和底层行为还是有帮助。
4. Composer autoload 原理是什么
标准回答
Composer 会根据 composer.json 配置生成自动加载文件,常见是 PSR-4 映射。运行时通过 autoload 文件把命名空间映射到具体目录,需要类时再自动加载对应文件。
你可以补的点
- PSR-4 最常见
- 也支持 classmap、files 等
- 现代 PHP 项目基本离不开自动加载
项目里怎么讲
像 Laravel、Yii 这类项目,自动加载是基础能力。大型项目里统一命名空间和目录结构,对协作和可维护性都很重要。
5. 什么是依赖注入,为什么有用
标准回答
依赖注入就是对象不自己 new 依赖,而是通过构造函数、方法参数或者容器把依赖传进来。好处是降低耦合、提升可测试性,也更方便做扩展和替换实现。
面试更稳的说法
依赖注入的核心不是“高级”,而是把对象创建和对象使用分开。复杂系统里,如果所有类都自己 new 依赖,后面很难维护和测试。
项目里怎么讲
你可以说:
在复杂业务系统里,像支付服务、归因服务、搜索服务这种外部依赖,我更倾向抽象成服务对象或接口,通过容器和依赖注入管理,而不是在业务逻辑里到处 new。
6. Laravel 服务容器解决什么问题
标准回答
Laravel 服务容器本质上是一个 IoC Container,用来管理对象创建、依赖解析和生命周期。它解决的是复杂系统里依赖关系越来越多时,手动 new 和依赖管理成本过高的问题。
可以补的点
bindsingleton- 自动解析构造函数依赖
- 服务提供者注册绑定关系
项目里怎么讲
像支付、归因、推送、搜索这类服务,如果通过容器管理,会比在业务逻辑里直接实例化更清晰,也方便扩展。
7. Laravel 中间件解决什么问题
标准回答
中间件主要用于请求进入控制器之前或响应返回之前做统一处理,比如鉴权、参数校验、限流、日志、跨域等。它把通用逻辑从控制器里抽出来,避免重复代码。
项目里怎么讲
我在项目里比较看重中间件层的职责边界,比如鉴权、灰度、日志、签名校验、基础风控这类逻辑,放中间件通常比塞在控制器里更合理。
8. session 和 cookie 区别
标准回答
- Cookie 存在客户端
- Session 服务端通常保存状态,客户端通过 Cookie 带 session_id 来关联
面试更稳的说法
Cookie 更适合少量客户端状态,Session 适合服务端会话管理。现代后端系统里,如果是 API 场景,很多时候也会用 token / JWT 替代传统 session。
9. 为什么现代后端 API 更倾向 token / JWT,而不是传统 session
标准回答
因为 API 服务往往是前后端分离、多端接入、甚至微服务化场景,token / JWT 更适合无状态认证和跨服务传递,而传统 session 更偏服务端会话模式。
你可以补的点
- JWT 不一定适合所有场景
- 如果要主动失效、踢登录、黑名单,就要补额外机制
10. 什么是面向对象设计里常见的设计模式
你最需要准备的不是死背 23 种,而是这几种:
- 工厂模式
- 单例模式
- 策略模式
- 责任链模式
- 模板方法
- 观察者模式
项目里怎么讲
- 策略模式:不同渠道回传规则
- 工厂模式:不同支付渠道 / 不同平台服务封装
- 责任链:审核流、规则过滤、事件处理链
11. 什么是单例模式,它有什么问题
标准回答
单例模式保证一个类全局只有一个实例。好处是统一访问共享资源,但缺点是容易隐藏依赖、增加耦合、影响测试,不应该滥用。
面试更稳的说法
配置中心、连接池这类资源可能适合单例,但业务服务一般不建议到处单例化。
12. PHP 数组为什么强大,但也要小心
标准回答
PHP 数组底层是哈希表,同时兼容了 map 和 list 的特性,使用很方便,但代价是内存占用较高,不适合无脑拿大数组做大规模数据处理。
项目里怎么讲
做批量处理、导入、报表、历史数据清洗时,我会注意避免一次性把太多数据加载到内存里。
13. 如何理解 PHP 的垃圾回收
标准回答
PHP 主要通过引用计数回收内存,对循环引用再配合 GC 机制处理。大多数 Web 请求是短生命周期,脚本结束时内存会整体回收,但长任务或 Swoole 场景下更要注意内存泄漏。
14. 什么是幂等,你在 PHP 项目里怎么做
标准回答
幂等就是同一个请求重复执行多次,结果仍然一致。支付回调、订单创建、退款、消息消费这些场景都要重点考虑幂等。
项目里怎么讲
我在 PHP 项目里会通过唯一键、状态机、Redis 锁、CAS 更新等手段做幂等,比如支付回调和订阅回调场景。
15. 一个复杂 PHP 项目,如何避免业务逻辑越来越乱
标准回答
我会做几件事:
- 按业务域拆模块
- 控制控制器只做入口层
- 复杂逻辑下沉到 service / logic 层
- 外部依赖做封装
- 用状态机、策略模式和统一日志降低复杂度
这个问题其实很适合你发挥
你可以说:
像订阅、支付、退款、归因这类复杂业务,如果都堆在 controller 里,后面一定会乱。我更习惯先把状态、服务边界和对外依赖拆清楚,再去写代码。
三、PHP 面试里很适合你主动讲的点
1. PHP 不是弱,只是场景不同
可以说:
我不觉得 PHP 适合所有场景,但在复杂业务规则、后台系统、需求变化快、协作密集的系统里,PHP 的落地效率和团队协作成本是很有优势的。
2. 复杂业务系统里的核心,不是写接口快
可以说:
我做 PHP 这些年最大的感受是,复杂系统里最重要的不是把接口写出来,而是状态、边界、异常场景和后续治理。
四、如果面试官继续追问
追问 1:你为什么现在还适合 PHP 岗
你可以答:
因为我过去几年主战场一直还是复杂业务系统,PHP 在这类业务里非常适合做快速且稳定的落地,我的经验优势也主要在这一层。
追问 2:PHP 和 Go 你怎么分工
你可以答:
PHP 我主要放复杂业务规则和后台能力,Go 我主要放实时链路、高并发处理和服务化部分。不是谁替代谁,而是按业务场景拆。
追问 3:PHP 做高并发是不是不合适
你可以答:
如果是极高并发、长链路、常驻服务,Go 会更适合;但很多高并发问题本质不只是语言问题,还包括缓存、异步、存储分层和链路设计。
五、你复习 PHP 最该背的 10 个点
- PHP-FPM 与 Nginx 协作
- Composer autoload
- interface / abstract / trait
- 依赖注入与服务容器
- Laravel 中间件
- session / cookie / token
- 设计模式
- PHP 数组和内存
- 幂等与复杂业务拆层
- PHP 和 Go 的分工边界