一、基礎知識題 (JS/PHP/SQL/正則)
1. HTML/JS 操作
<img title="aaaa" sina_title="bbbb" id="img1">
// 1) 獲取元素: document.getElementById('img1')
// 2) 獲取 title 屬性: element.title 或 element.getAttribute('title')
// 3) 獲取自定義屬性: element.getAttribute('sina_title') 或 element.sina_title (非標準)
2. PHP 序列化
序列化: serialize($arr)
反序列化: unserialize($str)
// JSON 替代: json_encode/json_decode (跨語言、可讀、安全)
3. URL 編碼差異
urlencode: 空格編碼為 +,基於 application/x-www-form-urlencoded
rawurlencode: 空格編碼為 %20,符合 RFC 3986,推薦用於 URL 路徑片段
4. HTML 過濾與轉義
過濾 (移除標簽): strip_tags($str, '') // 保留允許標簽
轉義 (實體化): htmlspecialchars($str, ENT_QUOTES, 'UTF-8') // 防 XSS
// htmlentities() 轉換所有 HTML 實體,較重
5. 正則過濾 JS 腳本
$pattern = '/<script\b[^>]*>.*?<\/script>/is';
// 更嚴格: 結合 HTMLPurifier 庫
6. SQL LEFT JOIN
LEFT JOIN: 返回左表所有行,右表匹配不到則為 NULL
-- 學生表 tl_user(id, name)
-- 成績表 tl_score(student_id, subject, score)
SELECT u.name,
SUM(IFNULL(s.score, 0)) AS total_score
FROM tl_user u
LEFT JOIN tl_score s ON u.id = s.student_id
GROUP BY u.id, u.name;
7. 執行系統命令函數
exec() // 最後一行輸出
shell_exec() // 完整輸出字串
system() // 直接輸出並返回最後一行
passthru() // 直接輸出二進制
proc_open() // 進程控制 (雙向管道)
// 安全: escapeshellarg(), escapeshellcmd()
8. JSON 處理
json_encode($arr) // 陣列/物件 → JSON 字串
json_decode($json, true) // JSON → 關聯陣列 (true 關鍵)
9. 變量檢測
isset($var) // 變量存在且非 null
empty($var) // 為空: "", 0, "0", null, false, [], 未定義
// 區別: isset($arr['key']) vs empty($arr['key'])
10. 錯誤報告區別
error_reporting(E_ALL) // 設定報告級別 (運行時)
ini_set('display_errors', '1') // 設定是否顯示 (輸出端)
// 生產: error_reporting(E_ALL), display_errors=0, log_errors=1
11. 預定義變量
客戶端 IP: $_SERVER['REMOTE_ADDR'] (注意代理: HTTP_X_FORWARDED_FOR)
來路 URL: $_SERVER['HTTP_REFERER'] (不可靠,可偽造)
12. 編碼轉換
iconv('UTF-8', 'GBK//IGNORE', $str) // 推薦
mb_convert_encoding($str, 'GBK', 'UTF-8') // 需 mbstring
13. 字符串分割/連接
explode($delimiter, $str) // 分割 → 陣列
implode($glue, $arr) // 連接 → 字串
// str_split() 按長度分割
14. 靜態方法調用
ClassName::staticMethod()
self::staticMethod() // 類內部
static::staticMethod() // 晚靜態綁定
二、MySQL 進階題
1. "MySQL server has gone away"
- 連接超時 (`wait_timeout` 默認 8h,長連接需重連)
- 數據包過大 (`max_allowed_packet`)
- Server 重啟/崩潰
- 客戶端發送查詢後連接已斷開
2. 靜態表 vs 動態表 / MyISAM vs InnoDB
| 特性 | MyISAM | InnoDB |
| 存儲引擎類型 | 非事務 | 事務 (ACID) |
| 鎖粒度 | 表鎖 | 行鎖 |
| 外鍵 | 不支援 | 支援 |
| 全文索引 | 支援 (5.6+ InnoDB 也支援) | 5.6+ 支援 |
| 崩潰恢復 | 差 | 優秀 (Redo/Undo Log) |
| 適用場景 | 只讀/讀多寫少、全文搜索 | 高併發寫入、事務、關鍵業務 |
3. 變量引用與 unset
$a = 1; $b = &$a;
unset($a); // $b 仍為 1 (引用計數: $a 釋放,$b 持有 zval)
unset($b); // $a 仍為 1
// 關鍵: unset 釋放變量名綁定,不銷毀值 (除非引用計數歸零)
三、演算法與代碼實作題
1. 獲取檔案後綴 (三種方法)
// 方法 1: pathinfo (推薦)
$ext = pathinfo('/as/image/bc.jpg', PATHINFO_EXTENSION); // "jpg"
// 方法 2: 正則
preg_match('/\.([^.]+)$/', $path, $m); $ext = $m[1] ?? '';
// 方法 3: 字符串操作
$ext = substr(strrchr($path, '.'), 1); // 包含點時需處理
2. 計算相對路徑
function getRelativePath($from, $to) {
$from = rtrim(dirname($from), '/') . '/';
$to = rtrim($to, '/');
$fromParts = explode('/', $from);
$toParts = explode('/', $to);
$i = 0;
while ($i < count($fromParts) && $i < count($toParts) && $fromParts[$i] === $toParts[$i]) $i++;
$up = count($fromParts) - $i;
return str_repeat('../', $up) . implode('/', array_slice($toParts, $i));
}
// 測試: $a='/a/b/c/d/e.php'; $b='/a/b/12/34/c.php' → '../../12/34/c.php'
3. 二分查找 (折半查找)
function binarySearch($arr, $target) {
$low = 0; $high = count($arr) - 1;
while ($low <= $high) {
$mid = $low + (($high - $low) >> 1);
if ($arr[$mid] === $target) return $mid;
if ($arr[$mid] < $target) $low = $mid + 1;
else $high = $mid - 1;
}
return -1; // 未找到
}
$array = [1,3,5,9,11,23,45,68,78,95,112,235,452];
echo binarySearch($array, 23); // 5
echo binarySearch($array, 100); // -1
面試加分項
- 能說出
isset/empty 底層 Zend VM 差異 (ISSET_IS_EMPTY_DIM_OBJ vs ISSET_ISEMPTY_VAR)
- 知道
rawurlencode 符合 RFC 3986,OAuth 簽名必須用它
- 能手寫相對路徑演算法並處理邊界 (同目錄、根目錄、.. 溢出)
- 理解 InnoDB 行鎖、MVCC、間隙鎖、Next-Key Lock 原理
- 知道 PHP 8.1+
readonly、never 返回類型、fibers 協程
此題庫覆蓋了中級 PHP 後端工程師核心能力模型:語言基礎、資料庫原理、演算法思維、工程安全意識。
- 上一篇文章: PHP 開發經驗談:引用 (&) 是個壞習慣 —— 內存與效能深度分析
- 下一篇文章: PHP 簡單圖片上傳實現:類型限制、大小控制、隨機命名與錯誤處理
Copyright ©
程式碼之家 All Rights Reserved