PHP temp_name和move_uploaded_file错误

时间:2016-10-14 06:30:37

标签: php file upload

我使用以下代码上传文件:

<?php include("./phpincludes/header.inc.php");

    $status = "";

    if(@$_POST['submit']){

        $pic = @$_FILES['pic']['name'];
        $pic_temp = @$_FILES['pic']['tmp_name'];
        $pic_type = @$_FILES['pic']['type'];
        $pic_size = @$_FILES['pic']['size'];

        $doc1 = @$_FILES['doc1']['name'];
        $doc1_temp = @$_FILES['doc1']['tmp_name'];
        $doc1_type = @$_FILES['doc1']['type'];
        $doc1_size = @$_FILES['doc1']['size'];

        $doc2 = @$_FILES['doc2']['name'];
        $doc2_temp = @$_FILES['doc2']['tmp_name'];
        $doc2_type = @$_FILES['doc2']['type'];
        $doc2_size = @$_FILES['doc2']['size'];

        $name = stripcslashes(htmlspecialchars(urldecode($_POST['name'])));
        $phone1 = stripcslashes(htmlspecialchars(urldecode($_POST['phone1'])));
        $phone2 = stripcslashes(htmlspecialchars(urldecode($_POST['phone2'])));
        $address = stripcslashes(htmlspecialchars(urldecode($_POST['address'])));
        $sec = stripcslashes(htmlspecialchars(urldecode($_POST['sec_amount'])));

        if($name != ""){


            if($pic_size <= 1048576){
                if (!$pic_temp) { // if file not chosen
                   echo "ERROR: Please browse for a file before clicking the upload button. ".$pic_temp;
                }
                $chars = "abcdefghijklmnopqrstuvrstwxyzABCDEFGHIJKLMNOPQRSTUVWXWZ0123456789";
                $rand_dir_name = $name." ".substr(str_shuffle($chars), 0, 6);

                mkdir("uploads/vendors/$rand_dir_name");
                move_uploaded_file($doc1_temp, "uploads/vendors/$rand_dir_name/$doc1");
                move_uploaded_file($doc2_temp, "uploads/vendors/$rand_dir_name/$doc2");
                if(move_uploaded_file($pic_temp, "uploads/vendors/$rand_dir_name/$pic")){
                    echo "uploads/vendors/$rand_dir_name/$pic";
                } else {
                    echo "move_uploaded_file function failed";
                }

            }else{
                echo "Image size should be less than 1 MB!";
            }

        }else{
            echo "Name is neccassary!";
        }


    }

?>

但问题是它在上传文件时给出了错误'错误:请在点击上传按钮之前浏览文件。'并且'move_uploaded_file函数失败'。我认为问题在于@在文件前面但是当我删除它时会给我一个未定义索引的错误。

我的HTML表单: -

<form method='POST' name='form'>
                <td><h4>Photo:</h4><input type='file' name='pic' accept="image/gif, image/jpeg, image/png"><h4>Full Name:</h4><input class='tableinput' type='text' placeholder='Name' name='name'></td>
                <td><h4>Phone 1:</h4><input class='tableinput' type='text' placeholder='Phone' name='phone1'>
                <h4>Phone 2:</h4><input class='tableinput' type='text' placeholder='Phone' name='phone2'></td>
                <td>
                    <h4>Document 1:</h4>
                    <input type='file' name='doc1'>

                    <h4>Document 2:</h4>
                    <input type='file' name='doc2'>
                </td>
                <td><h4>Service:</h4><input class='tableinput' type='text' placeholder='Service' name='services'>
                <h4>Address:</h4><input class='tableinput' type='text' placeholder='Address' name='address'></td>
                <td> <input class='tableinput' type='text' placeholder='Sercurity Amount' name='sec_amount'></td>
                <td >
                    <input type='submit' id='submit' name='submit' style='display:none;'/>
                    <i class='glyphicon glyphicon-ok-sign tableglyp blue' aria-hidden='true' onclick='submit()'>
                    </i>
                </td>
                </form>

请帮忙!

1 个答案:

答案 0 :(得分:0)

您的错误的主要原因是:

1)表单上的html不会传递文件,因为表单标记缺少属性

2)检查事物状态的逻辑是有缺陷的。

3)您正在非常手动地进行处理

4)谨慎使用@符号(几乎从不),您要修复错误

这是一个非常基本的上传脚本。首先,我想首先组织$_FILES数组,这使我对它更具可读性。最后,将所有业务逻辑转换为函数,以便您可以从页面中获取逻辑(当您想要使用它们时,可以包含它们):

<强> /functions/getFiles.php

function getFiles()
    {
        $files  =   array();
        foreach($_FILES as $keyname => $files) {
            foreach($_FILES[$keyname]['name'] as $key => $value) {
                if($_FILES[$keyname]['error'][$key] != 0)
                    continue;

                $file[$keyname][$key]['name']       =   $_FILES[$keyname]['name'][$key];
                $file[$keyname][$key]['type']       =   $_FILES[$keyname]['type'][$key];
                $file[$keyname][$key]['tmp_name']   =   $_FILES[$keyname]['tmp_name'][$key];
                $file[$keyname][$key]['error']      =   $_FILES[$keyname]['error'][$key];
                $file[$keyname][$key]['size']       =   $_FILES[$keyname]['size'][$key];
            }
        }

        return $file;
    }

此函数将转换$_FILES数组:

Array
(
    [pic] => Array
        (
            [name] => Array
                (
                    [0] => IMG_7506.JPG.jpeg
                )

            [type] => Array
                (
                    [0] => image/jpeg
                )

            [tmp_name] => Array
                (
                    [0] => /datatmp/phpTNMUP2
                )

            [error] => Array
                (
                    [0] => 0
                )

            [size] => Array
                (
                    [0] => 1003150
                )

        )

    [doc] => Array
        (
            [name] => Array
                (
                    [0] => gI_0_DiscoveryLogovertical1.jpg
                    [1] => gI_0_DiscoveryLogovertical2.jpg
                )

            [type] => Array
                (
                    [0] => image/jpeg
                    [1] => image/jpeg
                )

            [tmp_name] => Array
                (
                    [0] => /datatmp/phpjY1IYG
                    [1] => /datatmp/phpVsX37k
                )

            [error] => Array
                (
                    [0] => 0
                    [1] => 0
                )

            [size] => Array
                (
                    [0] => 43318
                    [1] => 43318
                )

        )

)

为:

Array
(
    [pic] => Array
        (
            [0] => Array
                (
                    [name] => IMG_7506.JPG.jpeg
                    [type] => image/jpeg
                    [tmp_name] => /datatmp/phpTNMUP2
                    [error] => 0
                    [size] => 1003150
                )

        )

    [doc] => Array
        (
            [0] => Array
                (
                    [name] => gI_0_DiscoveryLogovertical1.jpg
                    [type] => image/jpeg
                    [tmp_name] => /datatmp/phpjY1IYG
                    [error] => 0
                    [size] => 43318
                )

            [1] => Array
                (
                    [name] => gI_0_DiscoveryLogovertical2.jpg
                    [type] => image/jpeg
                    [tmp_name] => /datatmp/phpVsX37k
                    [error] => 0
                    [size] => 43318
                )

        )

)

现在您创建一个执行上传的功能。这是一个简单的例子:

<强> /functions/uploadFiles.php

function uploadFiles($files,$dir,&$errors,$max = 1048576)
    {
        if(!is_dir($dir)) {
            if(!mkdir($dir,0755,true))
                throw new Exception('Upload folder could not be created.');
        }

        foreach($files as $key => $file) {
            $name   =   preg_replace('/[^a-zA-Z0-9\.\-\_]/','',$file['name']);
            if(empty($name)) {
                $error[$key][]  =   'Name can not be empty.';
                continue;
            }

            if($file['size'] > $max) {
                $errors[$key][] =   htmlspecialchars($file['name']).' is too large ('.number_format($max/1024,0).' KB max)';
                continue;
            }

            if(!move_uploaded_file($file['tmp_name'],$dir.$file['name']))
                $errors[$key][] =   'File could not be uploaded';
        }
    }

将此作为可重复使用的功能更容易:

<强> /functions/createRandName.php

function createRandName($name)
    {
        $chars  =   "abcdefghijklmnopqrstuvrstwxyzABCDEFGHIJKLMNOPQRSTUVWXWZ0123456789";
        return $name." ".substr(str_shuffle($chars), 0, 6);
    }

使用:

# Include the functions here
require_once(__DIR__.'/functions/createRandName.php');
# ...etc.

# Set your error array
$errors =   array();

#check that a post is set
if(!empty($_POST['submit'])) {
    # Create the directory
    $dir    =   __DIR__.'/'.createRandName(preg_replace('/[^0-9a-zA-Z\s\_\-]/','',$_POST['name'])).'/';
    # Because the upload hinges on a folder being created first that doesn't
    # already exist, we want to stop the process as a whole if the directory
    # fails to be created
    try {
        # Organize the files and loop through them
        foreach(getFiles() as $input => $files) {
            # Upload the files
            uploadFiles($files,$dir,$errors);
        }
    }
    catch (Exception $e) {
        $errors[]   =   $e->getMessage();
    }
}
# Report errors
if(!empty($errors))
    print_r($errors);
?>

您的表单标记需要enctype='multipart/form-data'才能上传文件。您应该将所有文件名排列为pic[]doc[],即使您只有一个文件也是如此。这样你的文件都可以使用上面相同的上传机制。

<table>
    <form method='POST' name='form' enctype='multipart/form-data'>
        <td>
            <h4>Photo:</h4>
            <input type='file' name='pic[]' accept="image/gif, image/jpeg, image/png">
            <h4>Full Name:</h4>
            <input class='tableinput' type='text' placeholder='Name' name='name'>
        </td>
        <td>
            <h4>Phone 1:</h4>
            <input class='tableinput' type='text' placeholder='Phone' name='phone[1]'>
            <h4>Phone 2:</h4>
            <input class='tableinput' type='text' placeholder='Phone' name='phone[2]'></td>
        <td>
            <h4>Document 1:</h4>
            <input type='file' name='doc[]'>

            <h4>Document 2:</h4>
            <input type='file' name='doc[]'>
        </td>
        <td>
            <h4>Service:</h4>
            <input class='tableinput' type='text' placeholder='Service' name='services'>
            <h4>Address:</h4>
            <input class='tableinput' type='text' placeholder='Address' name='address'>
        </td>
        <td>
            <input class='tableinput' type='text' placeholder='Sercurity Amount' name='sec_amount'>
        </td>
        <td>
            <input type='submit' id='submit' name='submit' />
            <i class='glyphicon glyphicon-ok-sign tableglyp blue' aria-hidden='true' onclick='submit()'></i>
        </td>
    </form>
</table>

使用此表单布局,您的表单发布数组将如下所示:

Array
(
    [name] => My Name
    [phone] => Array
        (
            [1] => 123-123-1233
            [2] => 321-698-7894
        )

    [services] => Something
    [address] => 123 My Street
    [sec_amount] => 123
    [submit] => Submit
)