PHP:运行函数+ move_uploaded_file不行吗?

时间:2010-09-01 14:16:03

标签: php

在我的上传照片脚本中,在处理部分,当它将上传文件移动到uploaded_files时:

@move_uploaded_file($_FILES[$fieldname]['tmp_name'], $uploadFilename)
    or error('receiving directory insuffiecient permission', $uploadForm);

在此之前我添加了一个功能:

makeThumbnail($_FILES[$fieldname]['type'], $_FILES[$fieldname]['name'], $_FILES[$fieldname]['size'], $_FILES[$fieldname]['tmp_name'], 100);

使它成为缩略图。我希望原始图像是它的缩略图,但不知何故,只有删除makeThumbnail()move_uploaded_file(),然后我才能同时使用它们图像和缩略图......

我认为这是因为在执行其中一个之后tmp_name被删除了,所以我该怎样做才能保留它们?

我的拇指功能:

function makeThumbnail($type, $name, $size, $tmp_name, $thumbSize) {
    $path_thumbs = "uploaded_files/";       
    $img_thumb_width = $thumbSize; // 
    $extlimit = "yes"; //Limit allowed extensions? (no for all extensions allowed)

    //List of allowed extensions if extlimit = yes
    $limitedext = array(".gif",".jpg",".png",".jpeg",".bmp");

    //the image -> variables
    $file_type = $type;
    $file_name = $name;
    $file_size = $size; 
    $file_tmp = $tmp_name;

    //check if you have selected a file.
    if(!is_uploaded_file($file_tmp)){
        echo "Error: Please select a file to upload!. <br>--<a href=\"$_SERVER[PHP_SELF]\">back</a>";
        exit(); //exit the script and don't process the rest of it!
    }

    //check the file's extension
    $ext = strrchr($file_name,'.');
    $ext = strtolower($ext);

    //uh-oh! the file extension is not allowed!
    if (($extlimit == "yes") && (!in_array($ext,$limitedext))) {
        echo "Wrong file extension.  <br>--<a href=\"$_SERVER[PHP_SELF]\">back</a>";
        exit();
    }

    //so, whats the file's extension?
    $getExt = explode ('.', $file_name);
    $file_ext = $getExt[count($getExt)-1];

    //create a random file name
    $rand_name = md5(time());
    $rand_name= rand(0,999999999);

    //the new width variable
    $ThumbWidth = $img_thumb_width;

    /////////////////////////////////
    // CREATE THE THUMBNAIL //
    ////////////////////////////////

    //keep image type
    if($file_size){
        if($file_type == "image/pjpeg" || $file_type == "image/jpeg"){
            $new_img = imagecreatefromjpeg($file_tmp);
        }elseif($file_type == "image/x-png" || $file_type == "image/png"){
            $new_img = imagecreatefrompng($file_tmp);
        }elseif($file_type == "image/gif"){
            $new_img = imagecreatefromgif($file_tmp);
        }

        //list the width and height and keep the height ratio.
        list($width, $height) = getimagesize($file_tmp);

        //calculate the image ratio
        $imgratio=$width/$height;

        if ($imgratio>1){
            $newwidth = $ThumbWidth;
            $newheight = $ThumbWidth/$imgratio;
        }else{
            $newheight = $ThumbWidth;
            $newwidth = $ThumbWidth*$imgratio;
        }

        //function for resize image.
        if (function_exists(imagecreatetruecolor)){
            $resized_img = imagecreatetruecolor($newwidth,$newheight);
        }else{
            die("Error: Please make sure you have GD library ver 2+");
        }

        //the resizing is going on here!
        imagecopyresampled($resized_img, $new_img, 0, 0, 0, 0, $newwidth, $newheight, $width, $height);

        //finally, save the image
        ImageJpeg ($resized_img,"$path_thumbs/$rand_name.$file_ext", 100);
        ImageDestroy ($resized_img);
        ImageDestroy ($new_img);
    }

    //ok copy the finished file to the thumbnail directory
    // move_uploaded_file ($file_tmp, "$path_big/$rand_name.$file_ext");

    exit();
}

3 个答案:

答案 0 :(得分:2)

除非您已定义makeThumbnail()函数获取通过引用传递的参数,否则该函数内部的任何内容都无法删除$ _FILES数组中的原始数据。

但是,如果您在构建缩略图之前运行move_uploaded_files(),则会出现问题。它实际上将文件从$_FILES[...]['tmp_name']中指定的临时存储位置移动到目标文件名。然后,您的缩略图生成器将无处可用。

首先生成缩略图,事情应该更好。

作为安全提示,不要相信$ _FILES数组中的['type']参数。这是由客户设定的,可以伪造。最好确定使用getimagesize()fileinfo()获得哪种图像,这些图像纯服务器端。

随访:

男人,这是一些丑陋的代码。一些问题:

  1. 您提取文件扩展名两次,但使用的是用户提供的文件名,这是不安全的。
  2. 你已经使用过gd函数后检查'gd'库是否存在,所以检查完全没用。
  3. 您将$ _FILES数组的各个部分传递给函数,但只需将参数重新分配给其他变量,至少在一个案例中重新分配两次
  4. 您生成一个随机文件名,但它只是一个最多9位的数字,并且不检查是否有冲突,因此在某些时候,您将使用新上传覆盖旧图像。
  5. 您不会返回此随机文件名,那么您如何将随机命名的缩略图与原始图像相关联?
  6. 您没有检查上传是否正确完成。检查['size']参数是不够的。部分上传仍会有['size'],但文件会被截断并损坏。
  7. 您有一个基本的“允许类型”过滤器,但是如果您将其关闭并且用户上传.pdf,随机垃圾,或.exe,甚至GD不支持的图像类型该怎么办? / LI>

    因此,要解决此问题,请将函数调用更改为:

    makeThumbnail($_FILE[$fieldname], 100);
    

    当它们已经很好地分组到您的数组中时,没有理由手动传递所有这些参数。现在我们已经传入了所有可用的数据,我们可以开始做的事情了:

    function makeThumbnail($file, $thumbSize = 100) {
        if ($file['error'] !== UPLOAD_ERR_OK) {
            // something blew up
            // so handle error condition
            // 
            // error codes documentation: http://php.net/manual/en/features.file-upload.errors.php
            die();
        }
    
        $path_thumbs = "uploaded_files/";
        $allowed_types = array('image/jpeg', 'image/jpg', 'image/bmp', 'image/png', 'image/gif');
    
        $imageinfo = getimagesize($file['tmp_name']); // get image info
    
        if ($imageinfo === FALSE) {
            die("Uhoh. Unable to read uploaded file");
        }
    
        if (!in_array($imageinfo['mime'], $allowed_types)) {
            die("Sorry, images of type {$imageinfo['mime']} not allowed");
        }
    
        $rand_name = rand(0, 999999999); // this isn't particularly well done, but ...
    
        // create thumbnail
        switch($imageinfo['mime']) {
            case 'image/jpeg':
            case 'image/jpg':
                $new_img = imagecreatefromjpeg($file['tmp_name']);
                $file_ext = '.jpg';
                break;
            case 'image/gif':
                $new_img = imagecreatefromgif($file['tmp_name']);
                $file_ext = '.gif';
                break;
            case 'image/png':
                $new_img = imagecreatefrompng($file['tmp_name');
                $file_ext = '.png';
                break;
            default:
                die("Uhoh. How did we get here? Unsupported image type"):
        }
    
        $imgratio = $imageinfo['height'] / $imageinfo['width'];
        if ($imgratio > 1) {
            $newwidth = $thumbSize;
            $newheight = $thumbSize / $imgratio;
        } else {
            $newheight = $thumbSize;
            $newwidth = $thumbSize * $imgratio;
        }
    
        $resized_img = imagecreatefromtruecolor($newwidth, $newheight);
        imagecopyresampled($resized_img, $new_img, 0, 0, 0, 0, $newwidth, $newheight, $width, $height);
    
        $thumb_name = $rand_name . $file_ext;
        $thumb_path = $path_thumbs . '/' . $rand_name;
        imagejpeg($resized_img, $thumb_path);
    
        imagedestroy($resized_img);
        imagedestroy($new_img);
    
        return($thumb_name);
    }
    

    当然,这是未经测试的,只是从您的原始代码开始,而不是我的头脑,但它应该让您开始前往更好的工作。

答案 1 :(得分:0)

在移动临时文件后,您是否尝试创建缩略图?对我来说比在临时目录中工作更有意义。

答案 2 :(得分:0)

如果您认为临时变量会被覆盖某些地方,请将其保留在某处。 如果是这样那么它应该是这样的

$source=$_FILES[$fieldname]['tmp_name'];
$filename=$_FILES[$fieldname]['name'];

    @move_uploaded_file($source, $uploadFilename)
        or error('receiving directory insuffiecient permission', $uploadForm);

    makeThumbnail($_FILES[$fieldname]['type'], $filename, $_FILES[$fieldname]['size'], $source, 100);

但我认为不是这样,您移动的文件名和缩略图文件名是相同的。因此当缩略图功能在底部时,它只给你缩略图文件,因为它可以写入移动功能移动的原始文件。