ZetCode

PHP is_uploaded_file 函数

最后修改于 2025 年 4 月 3 日

PHP `is_uploaded_file` 函数用于检查文件是否是通过 HTTP POST 上传的。在 PHP 中处理文件上传时,这是一个关键的安全措施。

基本定义

`is_uploaded_file` 函数会验证文件是否存在并且是通过 HTTP POST 上传的。它有助于防止文件上传中的安全漏洞。

语法: `is_uploaded_file(string $filename): bool`。如果文件存在并且是通过 POST 上传的,则返回 true,否则返回 false。

基本文件上传验证

此示例使用 `is_uploaded_file` 来演示基本的文件上传验证。

basic_upload.php
<?php

declare(strict_types=1);

if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['userfile'])) {
    $tmpName = $_FILES['userfile']['tmp_name'];
    
    if (is_uploaded_file($tmpName)) {
        echo "File was uploaded via HTTP POST.";
    } else {
        echo "Potential file upload attack!";
    }
}

这会检查临时文件是否真的通过 POST 上传。在移动上传的文件之前,请务必使用此函数,以防止安全问题。

安全文件上传处理

本示例演示了一个完整的文件上传安全处理过程,包含验证。

secure_upload.php
<?php

declare(strict_types=1);

if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['document'])) {
    $uploadDir = __DIR__ . '/uploads/';
    $tmpName = $_FILES['document']['tmp_name'];
    $targetPath = $uploadDir . basename($_FILES['document']['name']);
    
    if (!is_uploaded_file($tmpName)) {
        die("Invalid file upload detected.");
    }
    
    if (move_uploaded_file($tmpName, $targetPath)) {
        echo "File uploaded successfully.";
    } else {
        echo "File upload failed.";
    }
}

这将 `is_uploaded_file` 与 `move_uploaded_file` 结合使用以进行安全处理。在将文件移动到其目标位置之前,请务必验证文件。

多个文件上传验证

此示例展示了如何一次性验证多个上传的文件。

multi_upload.php
<?php

declare(strict_types=1);

if ($_SERVER['REQUEST_METHOD'] === 'POST' && !empty($_FILES['photos'])) {
    foreach ($_FILES['photos']['tmp_name'] as $key => $tmpName) {
        if (!is_uploaded_file($tmpName)) {
            echo "File {$key} failed validation.";
            continue;
        }
        
        // Process valid files here
        echo "File {$key} is valid.";
    }
}

处理多个文件时,请单独验证每个文件。这可以防止恶意文件与合法文件一起被处理。

文件类型限制

将 `is_uploaded_file` 与文件类型检查结合使用以增强安全性。

type_check.php
<?php

declare(strict_types=1);

$allowedTypes = ['image/jpeg', 'image/png'];

if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['avatar'])) {
    $tmpName = $_FILES['avatar']['tmp_name'];
    $fileType = $_FILES['avatar']['type'];
    
    if (!is_uploaded_file($tmpName)) {
        die("Invalid file upload.");
    }
    
    if (!in_array($fileType, $allowedTypes, true)) {
        die("Only JPEG and PNG images are allowed.");
    }
    
    // Process the valid image
    echo "Image uploaded successfully.";
}

此检查会验证上传的有效性和文件类型。在检查允许的类型时,请务必使用严格比较,以防止类型混淆问题。

高级安全检查

此示例演示了全面的上传安全检查。

advanced_check.php
<?php

declare(strict_types=1);

function isSafeUpload(array $file): bool {
    if (!isset($file['tmp_name'], $file['error'])) {
        return false;
    }
    
    if ($file['error'] !== UPLOAD_ERR_OK) {
        return false;
    }
    
    if (!is_uploaded_file($file['tmp_name'])) {
        return false;
    }
    
    // Additional checks can be added here
    return true;
}

if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['resume'])) {
    if (isSafeUpload($_FILES['resume'])) {
        echo "File passed all security checks.";
    } else {
        echo "File upload rejected by security checks.";
    }
}

这会将多个安全检查合并到一个验证函数中。它会验证上传错误代码以及上传方法,以实现全面的保护。

最佳实践

常见错误

来源

PHP is_uploaded_file 文档

本教程涵盖了 PHP `is_uploaded_file` 函数,并提供了实际示例,演示了 PHP 中安全的文件上传验证。

作者

我叫 Jan Bodnar,是一名热情的程序员,拥有丰富的编程经验。自 2007 年以来,我一直在撰写编程文章。至今,我已撰写了 1400 多篇文章和 8 本电子书。我在编程教学方面有十多年的经验。

列出 所有 PHP 文件系统函数