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
英文地址,請注明出處:http://en.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…