首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 面試基礎題精選:高併發架構、IP 獲取、MySQL 建表與複雜查詢

     編輯:PHP 相關知識

PHP 面試基礎題精選:高併發架構、IP 獲取、MySQL 建表與複雜查詢

整理高頻基礎面試題,涵蓋架構設計、網絡編程、數據庫操作三大模塊,附標準答案與加分點解析。

一、大流量網站訪問量問題解決方案

標準回答(按優先級)

  1. 硬件評估:確認服務器 CPU、內存、磁盤 I/O、帶寬是否達標,必要時垂直擴容。
  2. 數據庫優化:索引優化、慢查詢分析、讀寫分離、分庫分表、引入 Redis/Memcached 緩存熱點數據。
  3. 防盜鏈:Nginx/Apache 配置 valid_referers,阻止圖片/視頻等靜態資源被外站直接引用消耗帶寬。
  4. 大文件下載控制:限速、斷點續傳、簽名鏈接防止外鏈盜取流量。
  5. 流量分流:DNS 輪詢、LVS/Nginx 反向代理、CDN 邊緣節點緩存靜態資源,將流量分散到多台應用服務器。
  6. 監控分析:部署 Prometheus+Grafana、ELK、SkyWalking 等,實時掌握 QPS、延遲、錯誤率,支撐決策。

加分點

  • 提及 熔斷降級(Sentinel/Hystrix)、限流(令牌桶/漏桶)、異步削峰(消息隊列)。
  • 說明 無狀態服務 設計,支撐水平擴容。

二、獲取客戶端 IP 與服務器 IP 代碼實現

客戶端 IP(兼容代理、負載均衡)

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'; // 未知
}

服務器 IP

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)。

三、MySQL 面試實戰:建表、關聯查詢、下拉菜單數據

1. 建表示例:文章表 message

CREATE 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='文章表';

2. 關聯查詢:文章列表含回復數,按回復數降序(無回復顯示 0)

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 中。

3. 分類下拉菜單數據獲取(PDO 防注入)

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>';

4. 進階考點:utf8 vs utf8mb4

  • SET NAMES utf8 僅支援 BMP 平面字符(3 字節),不支援 Emoji、生僻字。
  • 生產環境必須使用 utf8mb4(4 字節),表、列、連接、PHP 文件編碼全鏈路統一。
  • MySQL 8.0+ 默認字符集已為 utf8mb4。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved