繁体   English   中英

PHP文件上传+表单验证

[英]PHP File Upload + Form Validation

我想验证其他输入字段旁边的文件上传。 这听起来并不那么困难,但是如果我选择一个文件然后提交表格,那么当其他输入存在错误时,该文件也将被临时上传。

因此,用户必须修复此错误,然后必须再次选择文件:(。有没有一种用户友好的实现方式?

我当前的实现几乎如下:

我有一个简单的形式,像这样:

<form method="post" enctype="multipart/form-data">
    <input type="text" name="firstname" value="<?php echo $form->getFirstname() ?>" />
    <input type="text" name="lastname" value="<?php echo $form->getLastname() ?>" />
    <input type="file" name="file" />
    <input type="hidden" name="terms" value="false"/>
    <input type="checkbox" name="terms" value="terms" <?php if ($form->getTerms() === 'terms') echo 'checked' ?> />
    <input type="submit" name="send" value="send" />
</form>

因此,在提交此表单后,所有用户数据(例如名字,姓氏和字词)都将按照以下方式进行设置和验证:

if ( isset($_POST['send']) && $_POST['send'] === 'send' ) {

    if ( !\Fox\Validator::isString($_POST['firstname']) ) {
        \Fox\Validator::setError(1, 'firstname required');
    } else {
        $form->setFirstname($_POST['firstname']);
    }

    // ... other unimportant validations

    // validate file upload
    if (!isset($_FILES['file']['error']) || is_array($_FILES['file']['error'])) {

        \Fox\Validator::setError(10, 'error occurred');

    } else {

        // check error value
        switch ($_FILES['file']['error']) {

            // file exists
            case UPLOAD_ERR_OK:

                // check filesize (max filesize 100mb)
                if ($_FILES['file']['size'] > 104857600) {

                    \Fox\Validator::setError(10, 'max filesize overridden');

                } else {

                    $finfo = new finfo(FILEINFO_MIME_TYPE);

                    // define allowed mime types
                    $allowedMimeTypes = array(
                        'jpg' => 'image/jpeg',
                        'png' => 'image/png',
                        'gif' => 'image/gif',
                        'bmp' => 'image/bmp',
                        'bmp' => 'image/x-ms-bmp',
                        'bmp' => 'image/x-windows-bmp',
                        'mov' => 'video/quicktime',
                        'avi' => 'video/avi',
                        'avi' => 'video/msvideo',
                        'avi' => 'video/x-msvideo',
                        'mp4' => 'video/mp4',
                        'mpeg' => 'video/mpeg',
                        'mkv' => 'video/x-matroska',
                        'flv' => 'video/x-flv',
                        'wmv' => 'video/x-ms-wmv',
                    );

                    if (false === $ext = array_search($finfo->file($_FILES['file']['tmp_name']), $allowedMimeTypes, true)) {

                        \Fox\Validator::setError(10, 'file not supported');

                    }
                }

                break;

            case UPLOAD_ERR_NO_FILE:

                \Fox\Validator::setError(10, 'no file selected');
                break;

            case UPLOAD_ERR_INI_SIZE:
            case UPLOAD_ERR_FORM_SIZE:

                \Fox\Validator::setError(10, 'filesize overridden');
                break;

            default:

                \Fox\Validator::setError(10, 'error occurred');
        }

    }

    // check if form errors exists
    if (empty(\Fox\Validator::getError())) {

        // create unique filename
        $tmp = sha1_file($_FILES['file']['tmp_name']);

        // move file
        if (!move_uploaded_file($_FILES['file']['tmp_name'], sprintf('./Files/%s.%s', $tmp, $ext))) {

            \Fox\Validator::setError(10, 'error by uploading file');

        } else {

            header("Location: $successPage");
        }
    }
}

因此,如果不存在表单错误,则文件将被正确上载,并且用户将被重定向到成功页面,但是如果由于用户错过了必填字段(例如名字)而发生错误,那么文件也将通过Submit操作上载。但未保存,因此用户必须纠正输入错误并再次选择文件。

使用required HTML5属性,如下所示:

<form method="post" enctype="multipart/form-data">
    <input type="text" name="firstname" value="<?php echo $form->getFirstname() ?>" required/>
    <input type="text" name="lastname" value="<?php echo $form->getLastname() ?>" required/>
    <input type="file" name="file" required/>
    <input type="hidden" name="terms" value="false"/>
    <input type="checkbox" name="terms" value="terms" <?php if ($form->getTerms() === 'terms') echo 'checked' ?> required/>
    <input type="submit" name="send" value="send" />
</form>

如果未填写字段,浏览器将不允许用户发送表格

好的,我已经实现了Ryan Vincent在上面的评论中描述的解决方案,并且仅用于服务器端验证。

因此,如果存在其他形式错误,我会让上传的文件通过,然后将其上传到临时目录。 之后,我用成功消息和包含临时文件名的隐藏字段替换了表单的文件输入字段,因此,如果发生其他表单错误,该文件仍将保留在temp目录中,并且不能重新上传。 如果没有发生格式错误,则文件将从temp目录移至目标目录。

另外,cronjob将以特定的时间间隔刷新temp目录,未使用的文件将被删除。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM