2025 年 PHP 常见面试题整理以及对应答案和代码示例

2025 年 PHP 常见面试题整理以及对应答案和代码示例

PHP 面试通常会考察基础知识(数组、OOP、错误处理)和现代特性(类型、属性、枚举)。关键是要展示你能写出简洁、可预测的代码,同时了解 PHP 8+ 的新变化。

我整理了以下一些常见 PHP 可能面试的。每个问题都有简洁的答案和可运行的代码示例,你可以直接复制去试试。

原文链接- 2025 年 PHP 常见面试题整理以及对应答案和代码示例

PHP 8+ 中有哪些面试官关心的变化?

类型系统:联合类型(int|float)、mixed、never、true|false|null、交集类型,以及可空类型 ?T。

OOP 改进:构造器属性提升、readonly 属性/类、枚举、#[\Override] 属性。

控制流:match(表达式,无穿透)、nullsafe 操作符 ?->。

开发体验优化:命名参数、属性/注解、JIT(性能提升)、array_is_list()。

错误处理更合理:字符串和数字比较的方式改进了(比如 0 == “foo” 现在返回 false)。

如果你能清楚地解释这些特性,面试就会顺利很多。

PHP 中 == 和 === 的区别是什么?

== 执行类型转换;=== 要求相同类型和相同值。

var_dump(42 == "42");   // true  (宽松比较)
var_dump(42 === "42");  // false (严格比较)// 从 PHP 8 开始:
var_dump(0 == "foo");   // false (旧版本中曾经是 true)

要点:默认使用 ===,除非有非常具体的理由不这样做。

联合类型、可空类型和交集类型如何工作?

function area(int|float $w, int|float $h): float {return $w * $h;
}function greet(?string $name): string { // 可空类型return "Hello, " . ($name ?? "stranger");
}interface A { public function foo(): void; }
interface B { public function bar(): void; }class C implements A, B {public function foo(): void {}public function bar(): void {}
}function needsAandB(A&B $x): void { /* ... */ } // 交集类型
  • int|float 表示两者之一
  • ?string 表示 string|null
  • A&B 表示必须实现 A 和 B 两个接口

nullsafe 操作符是什么,何时应该使用?

当左侧为 null 时,它会自动停止后续的方法/属性访问。

$user = null;
echo $user?->profile?->company?->name ?? 'No company'; // "No company"

无需嵌套 if——简洁且安全。

什么时候应该使用 match 而不是 switch?

match 是表达式(可以返回值),必须处理所有情况,不会像 switch 那样穿透执行。

$status = 404;
$message = match ($status) {200, 201 => 'OK',404      => 'Not Found',500      => 'Server Error',default  => 'Unknown',
};

这减少了因遗忘 break; 引起的错误。

用 60 秒解释 Composer 自动加载和 PSR-4

  1. 在 composer.json 中添加命名空间
  2. 将文件放在正确的文件夹中
  3. 让 Composer 生成自动加载器
{"autoload": {"psr-4": {"App\\": "src/"}}
}
// src/Service/Pinger.php
namespace App\Service;class Pinger {public function ping(): string { return 'pong'; }
}
// index.php
require __DIR__ . '/vendor/autoload.php';use App\Service\Pinger;
echo (new Pinger())->ping(); // "pong"

修改后运行 composer dump-autoload

include 和 require 的区别(及 _once 变体)?

  • require → 失败时产生致命错误(停止脚本)
  • include → 失败时产生警告(继续执行)
  • *_once → 只加载文件一次

应用必须的文件使用 require(如 bootstrap),可选部分使用 include。

PHP 引用实际如何工作?

赋值是写时复制。大部分时候不需要用引用,只有在 API 必须修改参数值时才用。

function bump(int &$n): void { $n++; }
$x = 5;
bump($x);
echo $x; // 6

避免为"微优化"使用引用。它们往往损害清晰度。

解释异常与错误(Throwable)

所有可抛出的都实现 Throwable。Exception 和 Error 是兄弟类。

try {throw new RuntimeException('Oops');
} catch (\Throwable $e) { // 捕获 Exception 和 Errorerror_log($e->getMessage());
} finally {// 清理工作
}

在应用的边界层(比如控制器)捕获 Throwable 很方便,但在库的内部应该捕获更具体的异常类型。

PDO 预处理语句防止 SQL 注入

$pdo = new PDO($dsn, $user, $pass, [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
]);
$stmt = $pdo->prepare('SELECT * FROM users WHERE email = :email');
$stmt->execute(['email' => $email]);
$user = $stmt->fetch(PDO::FETCH_ASSOC);

经验法则:始终使用预处理语句;永不插入不可信输入。

如何正确存储密码?

使用 password_hash()password_verify()。不要自己选择算法——让 PHP 选择默认的。

$hash = password_hash($plainPassword, PASSWORD_DEFAULT);
if (password_verify($loginPassword, $hash)) {// 通过验证
}

PASSWORD_DEFAULT 会随着 PHP 版本更新而演进,当 password_needs_rehash() 返回 true 时需要重新哈希。

属性(Attributes)是什么,如何读取?

属性是原生注解。你可以装饰类、方法等,并通过反射读取。

#[Attribute(Attribute::TARGET_METHOD)]
class Route {public function __construct(public string $path) {}
}class BlogController {#[Route('/posts')]public function index() {}
}// 读取:
$ref = new ReflectionMethod(BlogController::class, 'index');
$attrs = $ref->getAttributes(Route::class);
$path  = $attrs[0]->newInstance()->path; // '/posts'

框架会用属性来处理路由、验证、依赖注入等功能。

枚举是什么,为什么有用?

枚举用真正的类型替换"字符串化"的常量。

enum Status: string {case Draft = 'draft';case Published = 'pub';
}function publish(Status $s): bool {return $s === Status::Published;
}publish(Status::Draft); // false

带值的枚举保证了比较的安全性,也能让 IDE 的自动完成更好用。

readonly 属性和不可变对象

用来创建值对象或 DTO 非常合适。

final class Money {public function __construct(public readonly int $cents,public readonly string $currency,) {}
}$m = new Money(100, 'USD');
// $m->cents = 200; // 错误

也可以用 readonly 类来让全部属性都变成只读。

Trait vs 抽象类 vs 接口

  • 接口:仅契约(无实现)
  • 抽象类:共享基类 + 部分实现
  • Trait:跨不相关类的水平复用(混入方法)
trait LoggerTrait {public function log($m){ echo $m; }
}interface Reportable {public function report(): string;
}abstract class BaseReport {abstract public function data(): array;
}class SalesReport extends BaseReport implements Reportable {use LoggerTrait;public function data(): array { return [1,2,3]; }public function report(): string { return json_encode($this->data()); }
}

延迟静态绑定(static:: vs self::)

self:: 绑定到写代码的类;static:: 延迟到运行时类。

class A {public static function who(): string { return __CLASS__; }public static function call(): string { return static::who(); }
}class B extends A {public static function who(): string { return __CLASS__; }
}echo B::call(); // "B" (延迟静态绑定)

基类如果要被继承的话,应该用 static::

生成器(yield)处理大数据集

生成器采用懒加载——特别适合处理大量数据流。

function lines(string $file): iterable {$fh = fopen($file, 'r');try {while (($line = fgets($fh)) !== false) {yield rtrim($line, "\n");}} finally {fclose($fh);}
}foreach (lines('huge.txt') as $line) {// 处理而不加载所有内容到内存
}

闭包、“use” 和箭头函数

$total = 0;
$add = function(int $n) use (&$total) { $total += $n; };array_map($add, [1,2,3]);
echo $total; // 6$double = fn($x) => $x * 2; // 箭头函数自动按值捕获

箭头函数写起来简洁,普通闭包能让你精确控制变量捕获(use)。

会话和 Cookie:安全默认检查清单

session_set_cookie_params(['httponly' => true,'samesite' => 'Lax','secure' => isset($_SERVER['HTTPS']),
]);
session_start();
$_SESSION['user_id'] = 123;
  • 登录时重新生成 ID(session_regenerate_id(true)
  • 设置 secure 和 httponly
  • 优先使用 SameSite=Lax 或 Strict,除非第三方流程需要 None

处理日期:优先使用 DateTimeImmutable

$start = new DateTimeImmutable('2025-03-01 09:00', new DateTimeZone('UTC'));
$meeting = $start->modify('+1 hour');echo $start->format('c');   // 未改变
echo $meeting->format('c'); // 新实例

不可变日期可以防止意外修改。记得要明确设置时区,或者早期用 default_timezone_set 设置。

OPcache 和性能基础

  • 生产环境启用 OPcache——它缓存编译的字节码
  • 避免过早的微优化;用专门的工具来测量性能(比如 Blackfire、Xdebug profiler)
  • 使用正确的数据结构;对大数字列表,SplFixedArray 比常规数组更节省内存

PHP 的垃圾收集器如何工作

PHP 使用引用计数 + 循环收集器的方式管理内存。大部分情况下不用操心这个问题。但如果是长时间运行的进程(比如 worker 或 daemon),又有大量数据结构或循环引用(父子对象互相引用),就需要手动 unset 引用并打破循环,这样能更早释放内存。

常见数组陷阱和高级技巧

$a = ['x' => 1, 'y' => 2];
$b = ['y' => 3, 'z' => 4];
$merge = $a + $b;           // 按键联合:['x'=>1,'y'=>2,'z'=>4]
$replace = array_merge($a, $b); // ['x'=>1,'y'=>3,'z'=>4]$list = ['a','b','c'];
array_splice($list, 1, 1); // 在索引1处移除:['a','c']
array_is_list(['a','b']);   // true(连续数字键)
array_is_list(['1'=>'a']);  // false

知道何时需要联合(+)vs 合并(array_merge)。

如何快速测试代码?

  • 将逻辑放入小函数或方法
  • 使用 PHPUnit 或 Pest;模拟外部服务
  • 快速检查,添加简单的 CLI 脚本:
if (PHP_SAPI === 'cli') {assert(area(3, 4) === 12.0);echo "All good\n";
}

CLI 断言能让你快速验证代码的正确性,即使只是小示例也很有用。

关于 PHP 中的异步

PHP 本身是同步的请求-响应模式,但 Fiber(PHP 8.1)让 AMPHP 或 ReactPHP 等库能实现用户空间的并发处理。面试中不会要求你手写异步代码,只要能说明白什么时候需要用(比如 worker 中有大量 I/O 操作)就行。

快速问答

$_POST vs php://input? $_POST 解析表单编码数据;php://input 读取原始请求体(对 JSON 有用)。

****get/**set?** 重载属性访问的魔术方法——谨慎使用。

__toString()? 对象的字符串表示(必须返回字符串)。

require_once 慢? 有 OPcache 时可忽略;为了正确性使用,不是"速度"。

到处都是静态方法? 对纯函数很方便;为了可测试性/可配置性优先使用 DI。

常量 vs 枚举? 枚举给你一个类型;常量只是值。

一个现代的 PHP 例子

<?php
declare(strict_types=1);enum Role: string {case User = 'user';case Admin = 'admin';
}final class User {public function __construct(public readonly int $id,public readonly string $email,public readonly Role $role,) {}
}#[Attribute(Attribute::TARGET_METHOD)]
class RequiresRole {public function __construct(public Role $role) {}
}final class UserController {#[RequiresRole(Role::Admin)]public function delete(User $actor, int $userId): string {if ($actor->role !== Role::Admin) {throw new RuntimeException('Forbidden');}// 假设我们在这里删除return "Deleted user #{$userId}";}
}// 小型反射驱动的守卫:
$ref = new ReflectionMethod(UserController::class, 'delete');
$attr = $ref->getAttributes(RequiresRole::class)[0] ?? null;
$required = $attr?->newInstance()->role ?? null;$controller = new UserController();
$admin = new User(1, 'a@ex.com', Role::Admin);
$guest = new User(2, 'g@ex.com', Role::User);echo $controller->delete($admin, 99), PHP_EOL; // "Deleted user #99"try {echo $controller->delete($guest, 99);
} catch (RuntimeException $e) {echo $e->getMessage(), PHP_EOL; // "Forbidden"
}

这个小片段展示了:严格类型、枚举、readonly 属性、属性和普通异常——所有"8.x 时代"的优点。

总结

如果你只记住一点:

  • 优先使用严格类型、预处理语句和 password_hash
  • 使用 match、nullsafe、枚举和 readonly 让意图明显
  • 保持代码可测试、小巧和朴实(以最好的方式)

面试看重的是思路清晰:要说明某个特性为什么存在,而不只是怎么用。如果你能为这些代码例子配上简洁的解释,答案就会很有说服力。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/100504.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/100504.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

系统性掌握 LangChain 的核心概念体系

二阶段&#xff1a;系统性掌握 LangChain 的核心概念体系 需要意识到&#xff1a;零散学习概念 ≠ 构建能力。 我们需要的不是“知道这些词”&#xff0c;而是“理解它们如何构成一个系统”。&#x1f3af; 目标在 4 周内&#xff0c;通过刻意练习和渐进式学习&#xff0c;系统…

【C++实战⑩】C++ 引用:解锁高效编程的密钥

目录一、引用的概念与定义1.1 引用的本质与语法规则1.2 引用与指针的区别与联系1.3 引用的初始化与使用注意事项二、引用作为函数参数实战2.1 引用参数的传递特点与优势2.2 引用参数实现函数修改外部数据2.3 引用参数与值参数、指针参数的对比三、引用作为函数返回值实战3.1 引…

微信支付回调成功通知到本地

微信支付回调成功通知到本地最近在本地调试微信支付需要用到支付成功回调&#xff0c;借助工具frp把微信支付成功回调通知到本地进行调试具体如下&#xff1a; 安装frp1.安装文档&#xff1a;https://gofrp.org/zh-cn/docs/setup/服务端准备一台公网上能正常访问的服务器&#…

Java的jdk21与 Go语言对比

JDK 21 的发布&#xff0c;特别是虚拟线程&#xff08;Virtual Threads&#xff09; 的引入&#xff0c;确实让 Java 在高并发领域的表现有了质的飞跃&#xff0c;也让大家更频繁地将其与 Go 这类天生并发友好的语言进行比较。下面我将从几个关键维度对它们进行梳理和对比&…

问答精选 | 《CATIA MODSIM SmartCAE 带练营》第三期 —— 设计迭代全流程直播答疑汇总(上)

目录 前情提要 ⭐点击观看完整版直播回放⭐ 概念问题 Q1.MODSIM是什么&#xff1f; Q2.SmartCAE是CATIA升级以后的新功能嘛&#xff1f;在哪个模块&#xff1f; 软\硬件适配问题 Q1.我们公司用的是V5&#xff0c;能用SmartCAE吗&#xff1f; Q2.我们公司的V5是2018版&a…

【进阶OpenCV】 光流估计--描绘运动物体轨迹

目录 前言 一、光流估计的核心原理 二、光流估计的计算流程 1. 特征提取&#xff1a;找到 “好跟踪” 的点 2. 光流计算&#xff1a;匹配帧间特征点 三、完整实现步骤&#xff08;附代码&#xff09; 1. 环境准备 2. 步骤 1&#xff1a;处理视频第一帧 3. 步骤 2&#…

InnoDB ACID实现:数据库可靠性的核心秘密

这段内容出自 MySQL 官方文档第 17.2 节《InnoDB 与 ACID 模型》&#xff0c;深入解释了 InnoDB 是如何实现 ACID 特性 的。ACID 是数据库系统中最核心的设计原则&#xff0c;确保数据在各种异常情况下依然可靠、一致、安全。 我们来逐部分解析并通俗理解&#xff1a;&#x1f…

CoolUtils Total Excel Converter:全能的 Excel 文件转换工具

一、软件简介 CoolUtils Total Excel Converter 是一款功能强大的 Excel 文件转换工具&#xff0c;专为高效处理和转换 Excel 文件而设计。它支持将 Excel 文件&#xff08;包括 XLS 和 XLSX 格式&#xff09;转换为多种常见的文件格式&#xff0c;如 PDF、CSV、HTML、TXT 等&…

告别静态图谱!TextSSL如何用「稀疏学习」实现更智能的文档分类?

文章链接&#xff1a;https://mp.weixin.qq.com/s/danmd9lSQpmck4tVsM37bQ 今天分享一篇将图神经网络应用于文本分类的创新模型——TextSSL。在传统的文档理解中&#xff0c;模型往往难以同时捕捉文本的局部句法细节和全局语义关联。针对这一挑战&#xff0c;TextSSL提出了一种…

开源商城mall项目功能评估与优化建议

项目地址&#xff1a;https://github.com/macrozheng/mall 开源项目是大多数程序员用来练手的最好途径&#xff0c;但是技术面和技术深度同样重要。一个商城项目能够称之为商城不光有基础的商品后台管理、移动端、支付管理&#xff0c;要打造一个全链路的生态系统&#xff0c;…

我的页面开发

我的页面开发 后端data\me_page.js我的页面静态数据module.exports () > {return {superCard: {beanCount: 1555,tips: "下单得5倍吃货豆,兑专享红包",},cards: [{label: "常用功能",size: 30,items: [{iconUrl: "/imgs/me_page/coupang.png"…

Java Swagger2 能显示页面但看不到一个接口

反复检查之后&#xff0c;发现问题出在的代码如下&#xff1a; ApiModelProperty(value "材料链接地址", example "{ApiHost}/storage/test.pdf")private String url; 结论&#xff1a;example的值包括了 { 和 } &#xff0c;导致网页解析的JSON数据失败…

2025年- H143-Lc344. 反转字符串(字符串)--Java版

1.题目2.思路 方法一&#xff1a;比如有5个元素 s[0],s[1],s[2],s[3],s[4] 反转之后对应 s[4],s[3],s[2],s[1],s[0] 所以s[0]s[4], s[1]s[3] s[i]s[n-1-i] 方法2:双指针 left0,rights.length-1; 当left<right的时候&#xff0c;交换两个元素的位置&#xff0c;左指针左移&am…

微服务高可用流程讲解

如何理解从前端nginx到后端微服务高可用架构问题&#xff0c;下面从nginx、gateway、nacos、各个服务节点的角度讲解下应该如何进行高可用&#xff0c;比如nginx是前端向后端进行的负载均衡&#xff0c;也相当于均衡地向各个gateway网关进行请求&#xff0c;再由gateway网关拉取…

留个档,Unity,Animation控制相机,出现抖动的问题记录

起因是项目用了一段高度自定义的过程复杂的相机Animation&#xff0c;来控制虚拟相机位移旋转。 发现在不同的电脑上&#xff0c;出现了不同程度的抖动。 搜索过程中&#xff0c;发现关键词&#xff1a;World Origin Rebasing。 Unity 世界坐标使用 float&#xff08;单精度浮点…

组合对冲策略(外汇版)

在复杂多变的外汇市场中&#xff0c;投资者常常面临着汇率波动带来的风险。为了降低这种风险&#xff0c;对冲策略成为了一种有效的风险管理工具。以下将详细介绍三种组合对冲策略&#xff0c;它们分别是基于多货币正负相关对冲、区域性货币对冲以及全日元货币对冲的策略。①多…

GPT-5-Codex 正式发布:迈向真正的“自主编程”时代

在 Anthropic Claude 近期遭遇争议的同时&#xff0c;OpenAI 推出了其编程领域的王牌产品——GPT-5-Codex。这并非简单的模型升级&#xff0c;而是基于 GPT-5 专为“自主编程”&#xff08;Autonomous Programming&#xff09;场景深度优化的专用版本&#xff0c;标志着 AI 编程…

java面试:了解redis的集群么,怎么通过redis的集群来实现redis的高可用?

我们知道&#xff0c;为了帮助数据库缓解高并发的压力&#xff0c;我们会上reids缓存帮助数据库分摊&#xff0c;虽说常见场景的并发量还不足以让redis宕机&#xff0c;但假设出现了极高的并发场景&#xff0c;redis依旧是有宕机的可能的&#xff0c;毕竟单点部署的redis容易出…

氧气科技亮相GDMS全球数字营销峰会,分享AI搜索时代GEO新观

2025年9月16日&#xff0c;全球数字营销领域的年度盛会——GDMS&#xff08;Global Digital Marketing Summit&#xff09;在上海国家会展中心盛大举行。作为品牌数字化转型的风向标&#xff0c;本届峰会汇聚来自全球的CEO、CMO、CDO及营销领域高管&#xff0c;共同探讨AI驱动下…

搭建Gin通用框架

Gin Web 开发脚手架技术文档 项目概述 本项目是一个基于 Gin 框架的 Go Web 开发脚手架模板&#xff0c;提供了完整的项目结构、配置管理、日志记录、MySQL 和 Redis 数据库连接等常用功能集成。 项目结构 gindemo/ ├── gindemo.exe # 编译后的可执行文件 ├── g…