整理高頻基礎面試題,涵蓋架構設計、網絡編程、數據庫操作三大模塊,附標準答案與加分點解析。
valid_referers,阻止圖片/視頻等靜態資源被外站直接引用消耗帶寬。function getClientIp(): string {
// 按優先級檢查頭部(需信任的代理層才可信)
$headers = [
'HTTP_CLIENT_IP', // 標準代理頭
'HTTP_X_FORWARDED_FOR', // 多層代理鏈,取第一個非未知 IP
'HTTP_X_REAL_IP', // Nginx proxy_set_header 設置
'REMOTE_ADDR', // 直接連接或最後一層代理
];
foreach ($headers as $header) {
$ip = $_SERVER[$header] ?? '';
// X-Forwarded-For 可能包含多個 IP,取第一個合法公網 IP
if ($header === 'HTTP_X_FORWARDED_FOR') {
$ips = array_map('trim', explode(',', $ip));
foreach ($ips as $single) {
if (filter_var($single, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
return $single;
}
}
} elseif (filter_var($ip, FILTER_VALIDATE_IP)) {
return $ip;
}
}
return '0.0.0.0'; // 未知
}
function getServerIp(): string {
// CLI 模式下 $_SERVER 可能無 SERVER_ADDR
if (php_sapi_name() === 'cli') {
return gethostbyname(gethostname());
}
return $_SERVER['SERVER_ADDR'] ?? $_SERVER['LOCAL_ADDR'] ?? getenv('SERVER_ADDR') ?? '127.0.0.1';
}
不可盲目信任
X-Forwarded-For。必須在 Nginx/負載均衡層配置real_ip_header和set_real_ip_from可信代理 IP 段,PHP 僅讀取$_SERVER['REMOTE_ADDR'](已被重寫為真實客戶端 IP)。
messageCREATE TABLE `message` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`title` VARCHAR(200) NOT NULL DEFAULT '',
`content` LONGTEXT,
`category_id` INT(11) NOT NULL DEFAULT 0,
`hits` INT(11) NOT NULL DEFAULT 0,
`created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `idx_category` (`category_id`),
KEY `idx_hits` (`hits`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='文章表';
SELECT
m.`id`,
m.`title`,
COALESCE(m.`hits`, 0) AS hits,
COUNT(c.`comment_id`) AS reply_count
FROM `message` m
LEFT JOIN `comment` c ON m.`id` = c.`id`
GROUP BY m.`id`
ORDER BY reply_count DESC, m.`id` DESC;
注意:COUNT(c.comment_id) 對 NULL 不計數,完美處理無回復情況。GROUP BY m.id 需配合 ONLY_FULL_GROUP_BY 模式(MySQL 5.7+ 默認開啟),SELECT 列必須聚合或在 GROUP BY 中。
function getCategoryOptions(PDO $pdo): array {
$stmt = $pdo->query("SELECT `category_id`, `category_name` FROM `category` ORDER BY `category_id`");
return $stmt->fetchAll(PDO::FETCH_KEY_PAIR); // 返回 [id => name] 關聯數組,直接用於 select options
}
// 前端渲染示例
echo '<select name="category_id">';
foreach (getCategoryOptions($pdo) as $id => $name) {
echo "<option value=\"$id\">" . htmlspecialchars($name) . "</option>";
}
echo '</select>';
utf8 vs utf8mb4SET NAMES utf8 僅支援 BMP 平面字符(3 字節),不支援 Emoji、生僻字。utf8mb4(4 字節),表、列、連接、PHP 文件編碼全鏈路統一。utf8mb4。