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

PHP 開發必備:7 個高頻實用工具函數庫

     編輯:PHP 相關知識

前言

在日常 PHP 開發中,反覆造輪子既低效又易出錯。本文整理了 7 個高頻場景的通用函數,涵蓋隨機字符串、中文截取、IP 獲取、目錄創建、郵箱驗證、跳轉提示、分頁組件,代碼經過現代化重構,可直接納入項目公共庫。

1. 生成隨機字符串

function random_string(int $length = 32): string {
    $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz';
    $bytes = random_bytes($length);
    $result = '';
    for ($i = 0; $i < $length; $i++) {
        $result .= $chars[$bytes[$i] % strlen($chars)];
    }
    return $result;
}
// 使用:random_string(16) → "aB3f9K..."

改進點: 棄用 `mt_rand`,改用 `random_bytes`(CSPRNG),安全性更高;移除 `mt_srand` 種子干擾。

2. 多字節安全截取(支援 UTF-8/GBK)

function mb_cut_string(string $str, int $length, string $suffix = '...'): string {
    if (mb_strlen($str) <= $length) return $str;
    return mb_substr($str, 0, $length) . $suffix;
}
// 使用:mb_cut_string("你好世界", 2) → "你好..."

說明: 原代碼僅支援 GB2312 且邏輯脆弱。現代項目統一 UTF-8,直接用 `mb_substr` 最可靠。

3. 獲取客戶端真實 IP(兼容代理)

function get_client_ip(): string {
    $headers = [
        'HTTP_CLIENT_IP',
        'HTTP_X_FORWARDED_FOR',
        'HTTP_X_FORWARDED',
        'HTTP_X_CLUSTER_CLIENT_IP',
        'HTTP_FORWARDED_FOR',
        'HTTP_FORWARDED',
        'REMOTE_ADDR'
    ];
    foreach ($headers as $header) {
        if (!empty($_SERVER[$header])) {
            $ips = explode(',', $_SERVER[$header]);
            foreach ($ips as $ip) {
                $ip = trim($ip);
                if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
                    return $ip;
                }
            }
        }
    }
    return $_SERVER['REMOTE_ADDR'] ?? '0.0.0.0';
}

增強: 遍歷多代理頭,過濾私有/保留地址,返回首個公網 IP。

4. 遞歸創建多級目錄

function ensure_dir(string $path, int $mode = 0755): bool {
    if (is_dir($path)) return true;
    $parent = dirname($path);
    if ($parent !== '.' && $parent !== '/') {
        ensure_dir($parent, $mode);
    }
    return @mkdir($path, $mode, true);
}

優化: 使用遞歸 + `mkdir($path, $mode, true)` 原生遞歸參數,代碼極簡。

5. RFC 5322 郵箱格式驗證

function is_valid_email(string $email): bool {
    return (bool)filter_var($email, FILTER_VALIDATE_EMAIL);
}
// 內部使用正則符合 RFC 5322,比手寫正則可靠得多

6. 統一跳轉提示組件

function redirect_with_msg(string $msg, string $url = '', int $wait = 3, string $title = '系統提示'): never {
    // 若為 AJAX 請求返回 JSON
    if (!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest') {
        header('Content-Type: application/json');
        exit(json_encode(['msg' => $msg, 'url' => $url, 'wait' => $wait]));
    }
    // 普通頁面輸出 HTML
    $html = <<<HTML
<!DOCTYPE html>
<html><head><meta charset="utf-8"><title>$title</title>
<meta http-equiv="refresh" content="$wait;url=$url">
<style>body{font-family:system-ui;padding:2rem;text-align:center;} .box{max-width:400px;margin:auto;border:1px solid #ddd;border-radius:8px;padding:2rem;box-shadow:0 2px 8px rgba(0,0,0,.1);} .btn{display:inline-block;margin-top:1rem;padding:.5rem 1.5rem;background:#007bff;color:#fff;border-radius:4px;text-decoration:none;}</style>
</head><body><div class="box"><h3>$title</h3><p>$msg</p>
HTML;
    if ($url) {
        $html .= "<a class=\"btn\" href=\"$url\">立即跳轉</a><p>{$wait}秒後自動跳轉...</p>";
    } else {
        $html .= "<a class=\"btn\" href=\"javascript:history.back()\">返回上一頁</a>";
    }
    $html .= "</div></body></html>";
    exit($html);
}

7. 通用分頁組件(PDO 版)

function paginate(PDO $pdo, string $baseSql, int $page = 1, int $perPage = 20, array $params = []): array {
    // 1. 總數查詢
    $countSql = "SELECT COUNT(*) FROM ({$baseSql}) AS t";
    $stmt = $pdo->prepare($countSql);
    $stmt->execute($params);
    $total = (int)$stmt->fetchColumn();
    
    // 2. 計算分頁
    $totalPages = max(1, (int)ceil($total / $perPage));
    $page = max(1, min($page, $totalPages));
    $offset = ($page - 1) * $perPage;
    
    // 3. 數據查詢
    $dataSql = "{$baseSql} LIMIT {$perPage} OFFSET {$offset}";
    $stmt = $pdo->prepare($dataSql);
    $stmt->execute($params);
    $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
    
    // 4. 生成鏈接
    $links = [];
    for ($i = max(1, $page - 2); $i <= min($totalPages, $page + 2); $i++) {
        $links[$i] = $i === $page ? "[$i]" : "$i";
    }
    
    return [
        'data' => $rows,
        'pagination' => [
            'current' => $page,
            'total' => $total,
            'per_page' => $perPage,
            'last_page' => $totalPages,
            'links' => $links,
        ]
    ];
}
// 使用:
// $result = paginate($pdo, "SELECT * FROM articles WHERE status=?", 1, 10, [1]);

最佳實踐建議

  • 將以上函數放入 `app/Common/Helper.php`,通過 Composer `files` 自動加載。
  • 嚴禁在視圖層直接使用 `print_r`/`var_dump`,統一用 `redirect_with_msg` 或 JSON API 返回。
  • 分頁組件已適配 PDO 預處理,**徹底杜絕 SQL 注入風險**。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved