I want to send an image through the php form with ajax, but for some reason I am not getting the $_FILES[] POST, but I do get the public POST of the publication and it is inserted into the database in the form correct, but I don't get anything from the POST of the image.
According to the errors that it shows in the image that I publish below, the error is due to the fact that in the PHP logic that I show at the end of this publication, nothing is coming through the $_FILES[] but I want you to know that if it does the $_POST['public'] and saves it to the database. What I don't know is the logic of publication.js , which is where the JS logic is located to send the form to publication.php , I don't know if it is correct.
HTML5 form:
<form id="form" method="POST" class="col s12" enctype="multipart/form-data">
<div class="row">
<div class="input-field col s12">
<textarea id="post" name="post" class="materialize-textarea" required></textarea>
<label for="post">Dile algo al mundo...</label>
<span class="helper-text" data-error="wrong" data-success="right">
<div class="file-field input-field">
<span class="file-path-wrapper">
<i class="material-icons prefix">photo_camera</i>
<input id="img" name="img" type="file">
</span>
</div>
</span>
</div>
</div>
<div id="respuesta"></div>
<!-- Boton de publicar -->
<button class="btn waves-effect btn-color right" id="submit" type="button" name="public">Publicar
<i class="material-icons left">send</i>
</button>
<p id="respuesta" class="red-text"></p>
</form>
JS code: $('#submit').click(function(){
var publicacion = document.getElementById('post').value;
var photo = document.getElementById('img').value;
// Enviar las variables a la ruta
var ruta = "public="+publicacion+"&img="+photo;
$.ajax({
url: './backend/publication.php',
type: 'POST',
data: ruta,
})
.done(function(res){
$('#respuesta').html(res)
})
.fail(function(){
console.log("error");
})
.always(function(){
console.log(publicacion);
});
});
PHP code:
<?php session_start();
require_once('../connection/connection.php');
$email = $_SESSION['email'];
require_once('../user/user.php');
require_once('../backend/publication.php');
// Obtener direccion ip del cliente
$ip = $_SERVER['REMOTE_ADDR'];
// Obtener el navegador del visitante
$browser = $_SERVER['HTTP_USER_AGENT'];
$errors = '';
$maxSize = 2097152; // 2 MB
if(isset($_POST['public'])){
$post = $_POST['public'];
$photo = $_FILES['img'];
// Obtenemos el nombre y la extension de la img
$photoName = $photo['name'];
// Obtenemos el tipo de la img
$photoType = $photo['type'];
// Asegurarnos que la imagen contenga un formato de img
if($photoType == "image/jpg" || $photoType == "image/png" || $photoType == "image/jpeg" || $photoType == "image/git" || $photoType == "image/gif" || $photoType == ""){
// Verificar el peso de la imagen
if($photo['size'] >= $maxSize) {
$errors = 'La imagen pesa mucho, por favor solo 2MB';
}
if(!is_dir('../photo')){
mkdir('../photo', 0777);
}
// Movemos la img a la carpeta photo
move_uploaded_file($photo['tmp_name'], '../photo/'.$photoName);
}else {
echo 'El tipo de imagen no es soportado';
}
// Limpiar
$post = htmlspecialchars($post);
$post = trim($post);
$post = filter_var($post, FILTER_SANITIZE_STRING);
// Si no hay errores, guardamos la pub en la BD
if($errors == ''){
$statement = $conexion->prepare('INSERT INTO publication (id_pub, id_user_pub, messeger_pub, photo_pub, ip_pub, browser_pub, create_at_pub) VALUES(
null, :id_user, :post, :photoName, :ip, :browser, NOW())'
);
$statement->execute(array(
':id_user' => $id_user,
':post' => $post,
':photoName' => $photoName,
':ip' => $ip,
':browser' => $browser
));
}
}
To send images or files you have to use
FormData
, you can't pass those values as part of a string. That's what multi-part means: Forms that submit files submit multiple parts, on the one hand the normal data that would be found in the ,$_POST
and the attachments, which would be found in the$_FILES
.If you look at the ajax part, I've added two options that are important when you use
FormData
,processData: false
to tell jQuery not to process the data, andcontentType: false
to tell jQuery not to set the content type.There are several ways to add the data to the object
FormData()
.If you need to send all the form inputs (files and text), you can simply do this:
var formData = new FormData(this);
and itFormData()
will collect all the form data:If, on the other hand, you only need to send specific form data, then you can add it by hand, using the
append
.For example:
For more details on
FormData()
you can consult the documentation on MDN .