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

PHP 開發者必知的 9 個實用函數與特性:func_get_args、glob、流操作、陣列解包等

     編輯:PHP 相關知識

    即使資深 PHP 開發者,也可能忽略一些強大但未被充分利用的函數。本文精選 9 個提升開發效率、簡化代碼的實用特性。

    1. 任意參數函數:func_get_args() / func_num_args() / func_get_arg()

    不定義固定參數,直接在函數內獲取所有傳入參數。

    <?php
    function logMessage() {
        $args = func_get_args();           // 所有參數陣列
        $count = func_num_args();          // 參數個數
        $first = func_get_arg(0);          // 第 1 個參數 (0-based)
    
        $msg = implode(' ', array_map(function($v) {
            return is_scalar($v) ? $v : json_encode($v, JSON_UNESCAPED_UNICODE);
        }, $args));
        error_log("[$count args] $msg");
    }
    
    logMessage('User login', ['id' => 1001, 'ip' => '192.168.1.1']);
    logMessage('Error', new Exception('DB connection failed'));
    /*
    [2 args] User login {"id":1001,"ip":"192.168.1.1"}
    [2 args] Error {"message":"DB connection failed","code":0,"file":"...","line":...}
    */
    ?>

    進階:PHP 5.6+ 可用 ... 運算子更優雅:function logMessage(...$args)。

    2. glob() — 模式匹配掃描檔案 (比 scandir() 強大)

    <?php
    // 所有 PHP 檔
    $phpFiles = glob('*.php');
    
    // 多副檔名 (需 GLOB_BRACE)
    $codeFiles = glob('*.{php,js,css,html}', GLOB_BRACE);
    
    // 遞歸掃描目錄 (PHP 5.5+ GLOB_BRACE + 生成器)
    function rglob($pattern, $flags = 0) {
        $files = glob($pattern, $flags);
        foreach (glob(dirname($pattern) . '/*', GLOB_ONLYDIR | GLOB_NOSORT) as $dir) {
            $files = array_merge($files, rglob($dir . '/' . basename($pattern), $flags));
        }
        return $files;
    }
    $allPhp = rglob('src/**/*.php'); // 需支援 ** (PHP 8.0+ 或自行實作)
    ?>

    常用旗標:GLOB_NOSORT (不排序,較快)、GLOB_ONLYDIR、GLOB_BRACE、GLOB_ERR (讀取錯誤目錄停止)。

    3. 陣列解包與合併:... 運算子 (PHP 7.4+)

    <?php
    $defaults = ['host' => 'localhost', 'port' => 3306, 'charset' => 'utf8'];
    $userCfg  = ['port' => 3307, 'db' => 'myapp'];
    
    $config = [...$defaults, ...$userCfg]; // 後者覆蓋前者
    // ['host'=>'localhost', 'port'=>3307, 'charset'=>'utf8', 'db'=>'myapp']
    
    // 函數調用解包
    function connect($host, $port, $charset, $db) { /* ... */ }
    connect(...$config); // 自動對應參數
    ?>

    4. 字串多行輸出:Heredoc / Nowdoc (PHP 5.3+)

    <?php
    $sql = << '2024-01-01'
    ORDER BY p.created_at DESC
    LIMIT 20
    SQL;
    
    echo $sql; // 保留換行、縮排,變數可插值
    
    // Nowdoc (單引號行為,不插值)
    $template = <<<'TPL'
    Hello {$name}, your code is {$code}.
    TPL;
    ?>

    5. 陣列去重保留鍵名:array_unique() + array_values() 重排

    <?php
    $data = [10, 20, 10, 30, 20, 40];
    $unique = array_values(array_unique($data)); // [10, 20, 30, 40] 鍵名重排 0..n
    
    // 物件去重 (需自定義比較)
    class User { public $id; public $name; }
    $users = [new User(1,'A'), new User(2,'B'), new User(1,'A')];
    $uniqueUsers = array_values(array_unique($users, SORT_REGULAR)); // PHP 7.2+ 支援物件比較
    ?>

    6. 記憶體高效讀取大檔:生成器 + SplFileObject

    <?php
    function readLargeCsv(string $file): Generator {
        $fh = new SplFileObject($file);
        $fh->setFlags(SplFileObject::READ_CSV | SplFileObject::READ_AHEAD | SplFileObject::SKIP_EMPTY);
        $fh->setCsvControl(','); // 分隔符
        foreach ($fh as $row) {
            yield $row; // 逐行產出,記憶體恆定
        }
    }
    
    foreach (readLargeCsv('huge.csv') as $i => $row) {
        if ($i === 0) continue; // 跳過標題
        // 處理 $row
        if ($i > 100000) break; // 測試只跑前 10 萬行
    }
    ?>

    7. 快速建立遞歸目錄:mkdir() 遞歸參數

    <?php
    // PHP 5.0+ 第三參數 recursive=true
    mkdir('/var/www/app/storage/logs/2024/05', 0775, true); // 一次建立多層目錄
    
    // 更安全:檢查是否存在、錯誤處理
    $dir = '/var/www/app/storage/logs/2024/05';
    if (!is_dir($dir) && !mkdir($dir, 0775, true) && !is_dir($dir)) {
        throw new RuntimeException("無法建立目錄: $dir");
    }
    ?>

    8. 取得客戶端真實 IP (支援代理/負載均衡)

    <?php
    function getClientIp(): 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 $h) {
            if (!empty($_SERVER[$h])) {
                $ips = explode(',', $_SERVER[$h]);
                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';
    }
    ?>

    9. 密碼雜湊驗證:password_hash() / password_verify() (PHP 5.5+)

    <?php
    // 註冊/修改密碼
    $hash = password_hash($plainPassword, PASSWORD_DEFAULT); // 自動生成鹽、選擇最強演算法 (目前 bcrypt/argon2)
    /* $hash 例:$2y$10$AbCdEfGhIjKlMnOpQrStUvWxYz1234567890abcd... */
    
    // 登入驗證
    if (password_verify($inputPassword, $hash)) {
        // 成功
        // 選擇性:檢查是否需重新雜湊 (演算法升級、cost 變更)
        if (password_needs_rehash($hash, PASSWORD_DEFAULT)) {
            $newHash = password_hash($inputPassword, PASSWORD_DEFAULT);
            // 更新資料庫
        }
    } else {
        // 失敗
    }
    ?>

    嚴禁 使用 md5()、sha1()、crypt() 自行雜湊密碼。

    總結速查表

    特性/函數最低版本核心優勢
    func_get_args() / ...4.0 / 5.6不定參數、避免 func_get_args() 陣列複製
    glob()4.3模式匹配、支援多副檔名、遞歸掃描
    陣列解包 ...7.4合併、函數調用、可讀性極佳
    Heredoc/Nowdoc5.3多行字串、SQL/模板無需轉義
    array_unique() + array_values()4.0 / 4.0去重並重排鍵名
    Generator + SplFileObject5.5 / 5.1大檔案恆定記憶體
    mkdir(..., true)5.0遞歸建立目錄
    取得真實 IP通用支援代理鏈、過濾私有/保留 IP
    password_hash() / password_verify()5.5標準化、未來兼容、防時序攻擊
    1. 上一篇文章:
    2. 下一篇文章:
    Copyright © 程式碼之家 All Rights Reserved