您的位置:

详解php上传

一、上传的基本概念

上传是指将本地文件传输到服务器上的操作,是web应用程序中常见的操作方式之一。常用于上传图片、视频、文档等文件。

上传操作需要用到form表单中的enctype属性,通常使用multipart/form-data。对于上传操作,服务器需要对接收到的文件进行处理,并返回处理结果。通常,上传的文件可以存储到服务器的磁盘中,也可以存储到数据库中。

二、上传文件的限制

为了确保上传操作的安全性和合法性,常常需要对上传的文件进行限制。常见的限制方式有:

1、文件类型:通过判断上传文件的后缀名或二进制头来限制文件类型。代码示例:

<?php  
$allowtype = array("jpg","gif","png");  
$filename = $_FILES['file']['name'];  
$extpart = pathinfo($filename);  
$exttype = strtolower($extpart['extension']);  
if (!in_array($exttype, $allowtype)) {  
    echo '非法的文件类型';  
}  
?>

2、文件大小:通过限制文件大小(单位:字节)来避免上传过大的文件。代码示例:

<?php  
$maxsize = 1024 * 1024 * 10; //10MB  
if ($_FILES['file']['size'] > $maxsize) {  
    echo '文件过大';  
}  
?>

三、上传文件的实现

php中,可以通过$_FILES来获取上传的文件信息。使用move_uploaded_file函数将文件保存到服务器的指定位置,并返回处理结果。以下是一个简单的文件上传处理代码:

<?php  
if ($_FILES['file'] && $_FILES['file']['error'] == UPLOAD_ERR_OK) {  
    $filename = $_FILES['file']['name'];  
    $tmpname = $_FILES['file']['tmp_name'];  
    $filesize = $_FILES['file']['size'];  
    $allowtype = array("jpg","gif","png");  
    $extpart = pathinfo($filename);  
    $exttype = strtolower($extpart['extension']);  
    //文件类型判断  
    if (!in_array($exttype, $allowtype)) {  
        echo '非法的文件类型';  
        exit;  
    }  
    //文件大小判断  
    $maxsize = 1024 * 1024 * 10; //10MB  
    if ($filesize > $maxsize) {  
        echo '文件过大';  
        exit;  
    }  
    //保存文件  
    $savepath = '/path/to/save/'.$filename;  
    if (move_uploaded_file($tmpname, $savepath)) {  
        echo '上传成功';  
    } else {  
        echo '上传失败';  
    }  
}  
?>

四、上传文件的进阶

除了基本的上传功能之外,还可以对上传文件进行进一步的处理,如压缩、裁剪等。以下是一个对图片文件进行压缩的示例代码:

<?php  
if ($_FILES['file'] && $_FILES['file']['error'] == UPLOAD_ERR_OK) {  
    $filename = $_FILES['file']['name'];  
    $tmpname = $_FILES['file']['tmp_name'];  
    $filesize = $_FILES['file']['size'];  
    $allowtype = array("jpg","gif","png");  
    $extpart = pathinfo($filename);  
    $exttype = strtolower($extpart['extension']);  
    //文件类型判断  
    if (!in_array($exttype, $allowtype)) {  
        echo '非法的文件类型';  
        exit;  
    }  
    //文件大小判断  
    $maxsize = 1024 * 1024 * 10; //10MB  
    if ($filesize > $maxsize) {  
        echo '文件过大';  
        exit;  
    }  
    //图片压缩  
    if ($exttype == 'jpg') {  
        $img = imagecreatefromjpeg($tmpname);  
        imagejpeg($img, $tmpname, 75);  
    } elseif ($exttype == 'png') {  
        $img = imagecreatefrompng($tmpname);  
        imagepng($img, $tmpname, 5);  
    } elseif ($exttype == 'gif') {  
        $img = imagecreatefromgif($tmpname);  
        imagegif($img, $tmpname, 75);  
    }  
  
    //保存文件  
    $savepath = '/path/to/save/'.$filename;  
    if (move_uploaded_file($tmpname, $savepath)) {  
        echo '上传成功';  
    } else {  
        echo '上传失败';  
    }  
}  
?>

五、上传文件的安全性

在上传操作中,常常需要注意文件的安全性。以下是一些常见安全性问题及解决方案:

1、文件名的安全性:上传的文件名往往是用户指定的,为了防止攻击,需要将文件名进行转义或重命名。代码示例:

<?php  
$filename = $_FILES['file']['name'];  
//转义文件名  
$filename = htmlspecialchars($filename, ENT_QUOTES, 'UTF-8');  
//生成随机文件名  
$randname = md5(uniqid(mt_rand()));  
$extpart = pathinfo($filename);  
$exttype = strtolower($extpart['extension']);  
$newname = $randname.'.'.$exttype;  
?>

2、文件内容的安全性:对上传的文件内容进行校验可以避免一些安全性问题。代码示例:

<?php  
if (isset($_FILES['file'])) {  
    $filetype = $_FILES['file']['type'];  
    if ($filetype != "" && $filetype != "image/jpeg" && $filetype != "image/pjpeg") {  
        echo '非法文件类型';  
    } else {  
        $filename = $_FILES['file']['name'];  
        $tmpname = $_FILES['file']['tmp_name'];  
        $filesize = $_FILES['file']['size'];  
        $savepath = '/path/to/save/'.$filename;  
        //检查文件安全  
        if (is_uploaded_file($tmpname)) {  
            if (move_uploaded_file($tmpname, $savepath)) {  
                echo '上传成功';  
            } else {  
                echo '上传失败';  
            }  
        } else {  
            echo '上传的文件不安全';  
        }  
    }  
}  
?>

六、上传文件的状态信息

上传文件时,常常需要获取上传的状态信息,以便显示给用户。以下是一个获取上传的进度信息的示例代码:

<?php  
$filepath = '/path/to/save/'.$filename;  
if ($_FILES) {  
    $filesize = $_FILES['file']['size'];  
    $tempname = $_FILES['file']['tmp_name'];  
    //上传进度信息  
    $loaded = 0;  
    $fp = fopen($tempname, 'rb');  
    while (!feof($fp)) {  
        $loaded += strlen(fread($fp, 4096));  
        if ($loaded % 1024 == 0) {  
            ob_flush();  
            flush();  
        }  
    }  
    fclose($fp);  
    //上传完成  
    if (move_uploaded_file($tempname, $filepath)) {  
        echo '上传完成';  
    } else {  
        echo '上传失败';  
    }  
}  
?>