2015-08-07 2 views
1

Я хочу проверить загрузку файла рядом с проверкой других полей ввода. Это звучит не так сложно, но если я выберу файл, а затем отправлю форму, файл будет также временно загружен, когда будут обнаружены ошибки других входов.Загрузка файла PHP + Проверка формы

Таким образом, пользователь должен исправить эту ошибку и затем выбрать файл снова :(Есть ли способ из дружественной реализации пользовательского

Моей текущая реализация выглядит почти следующим образом:.?

I имеет простую форму, как это:

<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> 

Таким образом, после отправки этой формы, все пользовательские данные, такие как Firstname, и фамилия условия будут установлены и проверены, как:

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"); 
     } 
    } 
} 

Таким образом, если ошибок формы не существует, файл будет загружен правильно, и пользователь будет перенаправлен на страницу успеха, но если произошла ошибка, так как пользователь пропустил требуемое поле ввода, например firstname, файл будет загружен через действие отправки тоже, но не сохранено, поэтому пользователю необходимо исправить ввод с ошибками и снова выбрать файл.

+0

Вы хотите, чтобы на входе был выбран тот же файл? – Sayed

+0

imo, один из способов сделать это: 1) файл загружается, и вы перемещаете его в «временную промежуточную область», пока не будет проверена вся другая информация. 1 a] Вы говорите пользователю, что загрузка файла была в порядке, но ждут каких-либо разрешений, которые вам нужны. 2) вы переместите его в «постоянную область». Вы говорите пользователю, что проверка данных хороша. Это все проверки валидации на стороне сервера. Вы очищаете «временную промежуточную зону» каждые несколько часов. –

+0

@phplover да, но это невозможно, или я не прав? – Fox

ответ

0

Хорошо, я реализовал решение, которое Райан Винсент, описанный в комментариях выше и работает только с проверкой на стороне сервера.

Таким образом, я разрешаю загруженному файлу проходить, если существуют другие ошибки формы и загружает его в каталог temp. После этого я заменяю поле ввода файла формы успешным сообщением и скрытым полем, которое содержит временное имя файла, поэтому, если возникают другие ошибки формы, файл по-прежнему сохраняется в каталоге temp и не должен быть перезагружен. Если ошибок формы не возникает, файл перемещается из каталога temp в целевой каталог.

В дополнение cronjob сбрасывает временную директорию в определенном интервалах, и неиспользуемые файлы будут удалены.

1

Использование HTML5 атрибута required, как это:

<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> 

Браузер не позволит пользователю отправить форму, если поля не заполнены

+0

Обратите внимание, что в целом валидация на стороне клиента не должна использоваться вместо проверки на стороне сервера, поскольку это открывает вам всевозможные проблемы, если люди пытаются отправить на сервер напрямую. – Gnarlywhale

+0

@Gnarlywhale Конечно, вам нужно поддерживать проверку на стороне сервера, но это помогает пользователю проверить его ввод – david8

+0

Комментарий был для Fox, так как исходный вопрос подразумевает, что они новы для разработки и могут не знать лучших практик. – Gnarlywhale

Смежные вопросы