Добрый день, коллеги!
Делаю админку для сайта-витрины stroytara.ru. Там админятся, в числе прочего, категории товаров и сами товары. Они хранятся в базе данных MySQL, оттуда же выводятся на сайт и в админку. Естественно, выводятся в цикле.
Проблема в том, что ниже приведенные коды отлично работают для:
а) одного, отдельно взятого изображения;
б) для первого изображения группы, выведенной в цикле. Для остальных - не срабатывает даже input type="file".
Вот, максимально упрощенные коды для категорий:
<?php foreach($categories as $cat) { ?>
<div class="container">
<!-- Аватар категории -->
<?php
$controller = new avatarController($captures[0], 'categories', 'category_avatar', $cat['category_avatar'], $cat['id']);
$controller->render_avatar();
?>
<div class="container">
<form>
Здесь выводим характеристики категории: id, описание и прочее + кнопку для обновления БД
</form>
</div>
</div>
<?php } ?>
Нас интересует только момент с заменой аватара. Контроллер и метод контроллера для аватара:
class avatarController {
protected $capture;
protected $table;
protected $field;
protected $filename;
protected $id;
public function __construct($capture, $table, $field, $filename, $id=NULL) {
$this->capture = $capture;
$this->table = $table;
$this->field = $field;
$this->filename = $filename;
$this->id = $id;
}
public function render_avatar() {
ob_start();
include("tmpl/change_avatar.tpl");
echo ob_get_clean();
}
}
Шаблон change_avatar:
<div class="container">
<div><?=$this->capture?></div>
<div><img id="preview" src="../images/<?=trim($this->filename);?>" /></div>
<div>
<form id="upload-image" name="upload-image" enctype="multipart/form-data">
<div class="form-group">
<div class="file-upload">
<label><input type="file" name="image" id="image" data-id="<?=$this->id?>"><span>Выбрать другой файл</span></label>
</div>
<div class="file-save">
<label><input id="save_logo" name="save_logo" type="submit"><span>Заменить и сохранить в медиабиблиотеке</span></label>
</div>
<input id="a_id" name="a_id" type="hidden" value="<?=$this->id?>" />
<input id="a_field" name="a_field" type="hidden" value="<?=$this->field?>" />
<input id="a_table" name="a_table" type="hidden" value="<?=$this->table?>" />
</div>
</form>
</div>
</div>
По задумке, после выбора файла для замены аватара картинка в img id="preview" обновляется, а сохранение новой картинки в БД делается PHP. Вот код JavaScript/Ajax для обновления картинки и передачи данных формы вывода аватара в php handler:
$(document).ready(function () {
$('#image').change(function(){
readImage(this);
});
function readImage ( input ) {
console.log('Reading image');
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
$('#preview').attr('src', e.target.result);
}
reader.readAsDataURL(input.files[0]);
}
}
$('#upload-image').on('submit',(function(e) {
e.preventDefault();
var formData = new FormData(this);
$.ajax({
type:'POST',
url: '.images.php',
data: formData,
cache:false,
contentType: false,
processData: false,
success:function(data){
console.log('success');
window.location.reload();
},
error:function(data){
console.log(data);
}
});
}));
});
И простейший php-обработчик (я убрал из кода все проверки, генерацию имени и прочий мусор):
$full_img_name = $_FILES['image'];
$filePath = $full_img_name['tmp_name'];
$errorCode = $full_img_name['error'];
$id = $_POST['a_id'];
$field = $_POST['a_field'];
$table = $_POST['a_table'];
$new_avatar = новое сгенерированное имя файла;
if (move_uploaded_file($filePath, 'images' . $new_avatar)) {
Database::setNewAvatar($new_avatar, $table, $field, $id);
}
else {
die('При записи изображения на диск произошла ошибка.');
}
?>
В методе setNewAvatar просто срабатывает UPDATE с переданными параметрами, код приводить не буду, он тривиален.