Как загрузить файл с помощью функции PHP move_uploaded_file

В какой-то момент своей карьеры вы захотите создавать настоящие динамические веб-приложения. Может решите написать свою социальную сеть. Как разработчик вы будете стараться заинтересовать пользователей, дать им возможность загружать фотографии, музыку, обмениваться файлами. На этот случай вам необходимо знать и уметь работать с функцией PHP move uploaded file.

Функция php move_uploaded_file()

Форма для сбора данных

PHP поддерживает загрузку любых файлов методом POST. Поэтому для передачи данных серверу, или сохранения их на локальную машину нужна HTML-форма. С помощью разметки выделите отдельное место, где бы пользователь мог выбрать файл. Сценарии нужно настроить все так, чтобы данные отправлялись без сбоев. Рассмотрим этот процесс на примере загрузки фотографии для профиля.

<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="POST" id="signup_form"  enctype="multipart/form-data">
	<fieldset>
        <label for="first_name">First Name:</label> 
        <input type="text" name="first_name" size="20">
        <label for="last_name">Last Name:</label> 
        <input type="text" name="last_name" size="20">
        <input type="hidden" name="MAX_FILE_SIZE" value="2000000">
        <label for="user_pic">Отправка изображения:</label>
        <input type="file" name="user_pic" size="30">
        <input type="submit" value="Отправить">
        <input type="reset" value="Очистить">
      </fieldset>
    </form>

Обратите внимание на атрибут enctype="multipart/form-data". Именно благодаря ему форма настроена на получение данных. Чтобы пользователи не придумали загружать котиков на 25 Мбайт, в поле hidden нужно обязательно установить ограничение на размер картинок. Для изображения профиля вполне достаточно 2 Мбайт, как в этом примере.

функция PHP move_uploaded_file

Отправка изображения

В форме выше в атрибуте action стоит <?php echo $_SERVER['PHP_SELF'];?>, означающий, что прием и обработка изображения будет происходить в этом же документе. Если вас это смущает и вы хотите, чтобы для каждого действия был свой отдельный скрипт, вставьте на место конструкции имя сценария, например, create_profile.php. Теперь весь код, включая работу с функцией PHP move uploaded file , записывайте в этом файле.

<?php
//собираю информацию из формы
$first_name = htmlspecialchars(trim($_REQUEST['first_name']));
$last_name = htmlspecialchars(trim($_REQUEST['last_name']));
//место хранения файлов
$uploads_dir = HOST_WWW_ROOT."uploads/profile_pics/";
$image_fieldname = "user_pic";

// Потенциальные PHP-ошибки отправки файлов
$php_errors = array(1 => 'Превышен макс. размер файла, указанный в php.ini',
2 => 'Превышен макс. размер файла, указанный в форме HTML',
3 => 'Была отправлена только часть файла',
4 => 'Файл для отправки не был выбран.');
//проверка ошибки при отправке файла
($_FILES[$image_fieldname]['error']==0) or
die("Возникла ошибка при отправке файла". $php_errors[$_FILES[$image_fieldname]['error']]);
//проверить нормальный ли файл отправляют, или это попытка взлома
@is_uploaded_file($_FILES[$image_fieldname]['tmp_name']) or 
die('Вы совершиете безнравственный поступок, позор!'."Имя файла: "."'{$_FILES[$image_fieldname]['tmp_name']}'");
//является ли отправляемый файл изображением
@getimagesize($_FILES[$image_fieldname]['tmp_name']) or die("Ошибочка! выбранный Вами файл не является изображением". "Имя файла {$_FILES[$image_fieldname]['tmp_name']}");
//присвоение загружаемому файлу уникального имени
$now = time();
while(file_exists($upload_filename = $uploads_dir.$now.'-'.$_FILES[$image_fieldname]['name'])){
  $now++;
}
?>

В коде присутствуют вспомогательные переменные:

  • В $upload_dir прописан путь к директории для загрузки. Вместо HOSW_WWW_ROOT пишите абсолютный путь к рабочему каталогу на сервере или у себя на компьютере.
  • Переменная $image_fieldname - это имя поля для изображения в HTML-форме.

Как видите, перед вызовом move uploaded file находятся строки, выполняющие проверку загружаемого изображения. Конечно, безопасные PHP-приложения — это миф, но должна присутствовать хотя бы минимальная защита.

Массив проверки ошибок $php_errors начинается не с нуля, а с единицы. Под индексом [0] стоит $_FILES[$image_fieldname]['error'], который в случае удачной загрузки возвращает число 0. В PHP $_FILES - это специальный массив, содержащий всю информацию о файле. Для доступа к этим данным используется индекс с именем поля ввода, которое мы ранее вывели в отдельную переменную $image_fieldname:

//проверка ошибки при отправке файла
($_FILES[$image_fieldname]['error']==0) or
die("Возникла ошибка при отправке файла". $php_errors[$_FILES[$image_fieldname]['error']]);

Когда move uploaded file PHP не работает

Вам кажется, что вы все сделали правильно, а интерпретатор выдает ошибку? Файл отказывается загружаться в назначенную директорию и появляется в абсолютно неожиданных местах? В первую очередь проверьте php.ini на разрешенный размер в параметре upload_max_filesize. Чаще всего такая ошибка возникает у Denver. Поэтому откройте php.ini (обычно он находиться в папке php) и просто установите нужный вам размер:

;;;;;;;;;;;;;;;;
; File Uploads ;
;;;;;;;;;;;;;;;;

; Whether to allow HTTP file uploads.
; http://php.net/file-uploads
file_uploads=On

; Temporary directory for HTTP uploaded files (will use system default if not
; specified).
; http://php.net/upload-tmp-dir
upload_tmp_dir="***"

; Maximum allowed size for uploaded files.
; http://php.net/upload-max-filesize
upload_max_filesize=5M

; Maximum number of files that can be uploaded via a single request
max_file_uploads=50

Если вы работаете на сервере, поинтересуйтесь у провайдера, файлы какого размера разрешено загружать. На бесплатном хостинге максимальный объем обычно 2 Мбайта. Вторая причина, по которой код может давать сбой, — неверно назначенная директория. Проверьте второй аргумент функции move_uploaded_file, он должен включать путь и обязательно имя.

Статья закончилась. Вопросы остались?
Комментарии 0
Подписаться
Я хочу получать
Правила публикации
Редактирование комментария возможно в течении пяти минут после его создания, либо до момента появления ответа на данный комментарий.