1

I'm working with PHP and AJAX calls, on a XAMPP server.

I've got this for with which you can upload a photo and some other info, as name, for example. The code is quite long, so I'll edit it a bit and put a short and very simple version of it in order to help you see what I have.

Form:

<form class="form-horizontal" role="form" action="" method="POST" enctype="multipart/form-data">
        <fieldset>
          <legend>My photo</legend>
            <img src="img/avatar-placeholder.jpg" class="center-block"/>
        </fieldset>


        <div class="form-group">
          <div class="col-md-12 text-center">
            <input name="pic" type="file" id="pic">
          </div>
        </div>

      <fieldset>
        <legend>My info</legend>
        <div class="col-md-6">
          <div class="form-group">
            <label class="col-sm-2 control-label" for="textinput">Name: </label>
            <div class="col-sm-10">
              <input type="text" placeholder="" class="form-control" id="name" name="name">
            </div>
          </div>
        </div>
      </fieldset>

      <button type="button" id="boton" class="btn boton2 textoBoldBlanco" onclick="addInfo()">Add Info <i class="fa fa-plus" aria-hidden="true" id="icono"></i></button>
</form>

The button of this form is related to a JS event in which I get the data and them make the AJAX call:

function addInfo(){

    picture = document.getElementById("pic").files[0].name;
    name = document.getElementById("name").value;

        $.ajax({

                url: "http://localhost/myProject/extras/processInfo.php", 
                type: "POST",
                data: {"picture": picture,
                       "name": name, 
                       },
                dataType: "html",
                cache: false,
                beforeSend: function() {    
                    console.log("Processing...");
                },
                success: 
                    function(data){
                        if(data == "SUCCESS"){
                            alert("Info added");
                        }else{
                            alert("Can't add info");
                        }
                    }

    });

}else{
    alert("Incorrect");
}

}

Now, this is the PHP file:

 if(isset($_POST['picture'])){

        $uploadDir = '../img/pictures/';

        $fileName = $_FILES['pic']['name'];
        $fileType = $_FILES['pic']['type'];
        $tmpName = $_FILES['pic']['tmp_name'];

        $filePath = $uploadDir . $fileName;
        $result = move_uploaded_file($tmpName, $filePath); 

}

if((isset($_POST['name'])) && (!empty($_POST['name']))){
    $name = $_POST['name'];
}else{
    $errores .= "<p class='alerta'>Error</p>";
}

//Query part
$stmt = $con->prepare("INSERT INTO info (picture, name) VALUES (?, ?)");

$stmt->bind_param('ss', $filePath, $name);

$stmt->execute();

$affectedRows = $stmt->affected_rows;

if($affectedRows > 0){
    echo "SUCCESS";
}else{
    echo "FAILED";
}

This is more or less the php code, NOTE: it already has a connection to the database working.

The problem is... after selecting a photo and adding a name, I get all the values correctly with JS (I've tried console.log() to check this) and then the AJAX call fires... and then it keeps saying "CAN'T ADD INFO", even though the info IS added to the database...

But, there is a second problem as well: despite the failed message, the path added to the database is not correct, it looks like this (like the variable $uploadDir only --> '../img/pictures/') and this is all that gets stored as a path... it seems as though it doesn't recognize the name of the file.

I suspect of the $_FILES[] part, because the POST receives a simple string, something like "myface.jpg" only --> in the JS file, I've done this "picture = document.getElementById("pic").files[0].name;" because if not, it says "C://fakepath" and the name of the file (I'm on Chrome)

Any ideas, help, would be appreciated :) thanks in advance!

xragdollqueen
  • 113
  • 4
  • 14

1 Answers1

1

The form has a name assigned for use by the Javascript/jQuery function but is otherwise the same as posted in the question.

<form name='uploads' class="form-horizontal" role="form" action="" method="POST" enctype="multipart/form-data">
        <fieldset>
          <legend>My photo</legend>
            <img src="/images/Grumpy_OK.jpg" class="center-block"/>
        </fieldset>


        <div class="form-group">
          <div class="col-md-12 text-center">
            <input name="pic" type="file" id="pic">
          </div>
        </div>

      <fieldset>
        <legend>My info</legend>
        <div class="col-md-6">
          <div class="form-group">
            <label class="col-sm-2 control-label" for="textinput">Name: </label>
            <div class="col-sm-10">
              <input type="text" placeholder="" class="form-control" id="name" name="name">
            </div>
          </div>
        </div>
      </fieldset>

      <button type="button" id="boton" class="btn boton2 textoBoldBlanco" onclick="addInfo()">Add Info <i class="fa fa-plus" aria-hidden="true" id="icono"></i></button>
</form>

The jQuery function uses the FormData Object to send the contents, including the file, to the PHP upload handler. The POSTed data that is sent will contain all the necessary data but you can always add other items to the POST array as shown below where I added the parameter fieldname.

function addInfo(){
    var form=document.forms['uploads'];
    var data=new FormData( form );
        data.append('fieldname','pic');


    $.ajax({
        url: '/test/uploadhandler.php',/* Change this to your upload handler script */
        data: data,
        type: 'POST',
        contentType: false,
        processData: false,
        cache: false,
        beforeSend: function() {    
            console.log("Processing...");
        },
        success: function(r){
            alert( r == 'SUCCESS' ? 'Info added' : 'Can\'t add info' );
        }
    });
}

The PHP script for processing the upload ~ not fully tested because of filesystem structure and db but the actual upload was tested using a different target directory.

if( $_SERVER['REQUEST_METHOD']=='POST' && isset( $_POST['name'], $_POST['fieldname'] ) ){

    $name=$_POST['name'];
    $action=$_POST['action'];
    $fieldname=$_POST['fieldname'];

    $uploadDir = '../img/pictures/';

    function uploaderror( $code ){ 
        switch( $code ) { 
            case UPLOAD_ERR_INI_SIZE: return "The uploaded file exceeds the upload_max_filesize directive in php.ini"; 
            case UPLOAD_ERR_FORM_SIZE: return "The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form"; 
            case UPLOAD_ERR_PARTIAL: return "The uploaded file was only partially uploaded"; 
            case UPLOAD_ERR_NO_FILE: return "No file was uploaded"; 
            case UPLOAD_ERR_NO_TMP_DIR: return "Missing a temporary folder"; 
            case UPLOAD_ERR_CANT_WRITE: return "Failed to write file to disk"; 
            case UPLOAD_ERR_EXTENSION: return "File upload stopped by extension"; 
            default: return "Unknown upload error";
        }
    }

    if( $action=='fileupload' ){
        $obj=(object)$_FILES[ $fieldname ];

        $name=$obj->name;
        $tmp=$obj->tmp_name;
        $size=$obj->size;
        $type=$obj->type;
        $error=$obj->error;

        if( $error == UPLOAD_ERR_OK ){

            $ext=pathinfo( $name, PATHINFO_EXTENSION );
            $targetpath = $uploadDir . $name;
            /* You might want to do some sanity checks on the submitted data and image */

            /* Move the file to it's new location */
            $status = move_uploaded_file( $tmp, $targetpath );



            if( $status ){

                $sql='insert into `info` (`picture`, `name`) values ( ?, ? )';
                $stmt = $con->prepare( $sql );

                if( $stmt ){

                    $stmt->bind_param('ss',$targetpath,$name);
                    $result=$stmt->execute();
                    $rows = $result ? $stmt->affected_rows : 0;

                    exit( $result & $rows ? 'SUCCESS' : 'FAILED' );
                }
            }


        } else {
            exit( uploaderror( $error ) );
        }
    }
}
Professor Abronsius
  • 33,063
  • 5
  • 32
  • 46
  • @RamRider Hi! Thanks for the reply! I actually had to use this method, but had to call the form by its id, as a comment in this thread --> https://stackoverflow.com/questions/20375461/ajax-post-request-via-jquery-and-formdata-post-empty-on-php, otherwise it didn't work. Thanks! I'd never used formData like that before. – xragdollqueen Jun 25 '17 at 04:02