Problemas para que me grabe el nombre de un fichero en una BD viniendo de un formulario. Os pongo lo importante del codigo.
<form method="post" name="form" enctype="multipart/form-data" action=""> //formulario
<label for="foto">Imagen</label>
<input type="file" id="foto" name="foto" class="form-control">
<input type="button" name="art_button" id="art_button" value="Registrar" class="btn btn-success btn-lg" > //hasta aqui lo principal del formulario
// esto es todo lo de ajax
$("#art_button").click(function(event){
event.preventDefault();
var formData = new FormData();
var files = $('#foto')[0].files[0];
formData.append('file',files);
$.ajax({
url : "articulosalta.php",
method : "POST",
data : $("form").serialize(), formData,
success : function(data){
$("#art_msg").html(data);
}
})
})
// el art_msg es donde me saldran los mensajes debajo del formulario
en el fichero articulosalta.php tengo
<?php
include "db.php";
$p_desc=$_POST["p_desc"];
$categoria = $_POST["categoria"];
$marca=$_POST["marca"];
$descripcion=$_POST['descripcion'];
$precio=$_POST["precio"];
$imagen=$_FILES["foto"]["name"];
$name="/^[A-Za-z0-9s]+$/";
$number="/^[0-9]+$/";
if (empty($p_desc) || empty($categoria) || empty($marca) || empty($descripcion) || empty($precio) || empty($imagen)){
echo "
<div class='alert alert-warning'>
<a href='#' class='close' data-dismiss='alert' aria-label='close'>×</a><b>Por favor rellene todos los campos</b>
</div>
";
exit();
} else {
// y asi voy haciendo comparaciones de campos para que este todo correcto. Si le quito el formdata y las variables en el ajax, me graba perfectametne el registro sin el fichero, pero al poner el fichero no me funciona, me pone undefined index foto en "articulosalta.php" linea 10
El fallo más típico con subida de ficheros por AJAX es mandar el formulario como si fuera texto normal, cuando un fichero necesita ir como multipart/form-data de verdad, con FormData.
Con jQuery, el error habitual es no desactivar el procesado automático que jQuery hace por defecto, que rompe el FormData:
var datos = new FormData(document.getElementById('form'));
$.ajax({
url: 'guardar.php',
type: 'POST',
data: datos,
processData: false, // ¡importante! si no, jQuery intenta serializar el FormData como si fuera un objeto normal
contentType: false, // ¡importante! si no, jQuery pone un content-type que rompe el multipart
success: function(resp) { console.log(resp); }
});
Esos dos flags (processData: false y contentType: false) son los que casi siempre falta poner, y sin ellos el fichero llega vacío o corrupto al servidor aunque el resto del formulario funcione bien.
En el lado PHP, el fichero te llega en $_FILES['foto'] como siempre, exactamente igual que si el formulario se hubiese enviado sin AJAX. Ahí ya puedes sacar el nombre con $_FILES['foto']['name'] y guardarlo en la BD junto con el resto de datos del POST.
Carlos