Иногда на стеке встречается вопрос от новичков - как заменить файл, принадлежащий некоторой сущности. Допустим, в программе есть сущность Книга, и у нее есть файл обложки. Когда книга редактируется - файл обложки может быть изменен.
Многие начинающие разработчики будут полагать, что путь к текущему файлу обложки надо выводить на форму редактирования, затем, аналогично полям <input type="text" />
, добавлять его значение в запрос\метод\функцию обновления. По их мнению получается, что если файл не был обновлен, то в БД запишется то же самое значение пути к файлу, что есть в БД сейчас. Выглядит это в их голове как-то так:
if (isset($_POST['update-btn'])) {
$name = $_POST['name'];
// вроде как тут должен быть путь к файлу,
// но <input type="file" /> работает не так
$file = $_POST['file'];
$query = "UPDATE tbl_book SET name = '$name', filepath = '$file' WHERE id = 42";
$dbh->execute($query);
}
Как следствие, у них возникает вопрос - как вывести текущий путь к файлу в <input type="file" />
? Ответ прост - никак. Нужно понять две вещи: первое - никакое значение от сервера в <input type="file" />
предустановить нельзя. Второе - работать с заменой файла следует иначе, чем с заменой текстовых значений.
Поэтому правильный алгоритм обновления файла выглядит так:
1. На форме обновления рядом с полем загрузки файла (<input type="file" />
) выводим текущий файл, например: Текущая обложка <img src="path/to/file.jpg" />
. Так как в общем случае никому не интересно, как файл назван в системе, то такого вывода достаточно: пользователь видит содержимое файла (собственно картинку) и может решить - следует ли загрузить новый файл. Если же действительно надо показать текущий путь к файлу, то выводим, например, Текущий файл расположен по пути "path/to/file.jpg"
. В обоих случаях path/to/file.jpg
- это путь к файлу, хранящийся в БД.
В поле загрузки файла пользователь может загрузить новый файл, а может не загрузить. Поэтому дальше идут два варианта развития событий.
2.1. Пользователь не загрузил файл. Значит, в запросе\методе\функции обновления записи не требуется указывать поле с файлом.
2.2. Пользователь загрузил новый файл. Значит, надо этот файл сохранить в каком-то каталоге и сформировать путь к нему. Далее, в запросе\методе\функции обновления записи указать путь к новому файлу, и после успешного обновления записи удалить с диска старый файл. Старый файл можно и не удалять, если на диске достаточно места.
Схематично код выглядит так, его аналоги можно реализовать в любом фреймворке:
if (isset($_POST['update-btn'])) {
$name = $_POST['name'];
if ($_FILES['file']) {
move_uploaded_file();
$file = 'path/to/file.jpg';
// опционально, за этим значением нужно сходить в БД
$oldFile = 'path/to/old_file.jpg';
}
if (isset($file)) {
$query = "UPDATE tbl_book SET name = '$name', filepath = '$file' WHERE id = 42";
} else {
$query = "UPDATE tbl_book SET name = '$name' WHERE id = 42";
}
$dbh->execute($query);
// опционально
unlink($oldFile);
}
Это всё, что требуется сделать в случае замены файла в сущности. Никаких костылей изобретать не требуется.
Комментариев нет:
Отправить комментарий