0

I am using ajax form to display form dynamically in which it contains the file upload option. I'm getting the post values of every text values but the File array is empty. I have executed print_r($_POST) and print_r($_FILES) to see the post data, the $_FILES Array is showing null value.

Here is the form I'm using.

<form class="form-3 form-horizontal ajxfrm" id="step-three" enctype="multipart/form-data" action="<?php echo $html->addLink(array('controller'=>'homes','action'=>'step_three_ajax')); ?>" method="post">
<div id="calendar">
    <div class="clear"></div>
    <div style="position:relative">
        <div class="control-group">
            <div class="control-label"><label class="control-label">Name</label></div>
            <div class="controls"><input id="name" type="text" name="name" /></div>
        </div>
    </div>
    <div style="position:relative">
        <div class="control-group">
            <div class="control-label">Email</div>
            <div class="controls"><input id="email" type="text" name="email" /></div>
        </div>
    </div>
    <div style="position:relative">
        <div class="control-group">
            <div class="control-label">Contact</div>
            <div class="controls"><input id="contact" type="text" name="contact" /></div>
        </div>
    </div>
    <div style="position:relative">
        <div class="control-group">
            <div class="control-label">Files<br/><span style="font-size:10px; font-style:italic">(Optional)</span></div>
            <div class="controls">
                <input id="fileupload" type="file" name="fileupload" /><br/>
            </div>
        </div>
    </div>
    <div style="position:relative">
        <div class="control-group">
            <div class="control-label">Your Message</div>
            <div class="controls"><textarea id="message" rows="3" name="message"></textarea></div>
        </div>
    </div>
    <div class="clear"></div>
</div>
<div id="submit">       
    <input type="hidden" name="post" value="1"/>
    <input type="submit" class="btn green" value="Next"/> 
</div>
</form>

Here is the ajax call

$('.ajxfrm').live('submit',function(){
    var thisObj = this;
    var submit = true;
    if('step-two'==$(thisObj).attr('id')){
        submit = stepTwo();
    }else if('step-three'==$(thisObj).attr('id')){
        submit = stepThree();
    }           
    if(submit){
        $.ajax({
            type: "POST",
            data: $(thisObj).serialize(),
            url: $(thisObj).attr('action'),
            beforeSend: function(){
                showOverLayer();
            },
            success: function(data){
                $(thisObj).parent("#content").empty().html(data).hide().fadeIn(function(){
                    setBlocks();
                    setLiClick();
                    hideOverLayer();
                });
                changeCalNaviHref();
            }
        });
    }
    return false;
});

Here im calling the upload function using $booker->uploadfiles(); in controller here is the controller method function

public function step_three(){
    //save booking
    if(isset($_POST['post'])){
        $booker = new Booker();     
        //create booker
        $_SESSION['userdat']['name']=$_POST['name'];
        $_SESSION['userdat']['email']=$_POST['email'];
        $_SESSION['userdat']['contact']=$_POST['contact'];
        $_SESSION['userdat']['message']=$_POST['message'];

        if($booker->setsessions($_SESSION['userdat']))
        {
            $booker->uploadfiles();
            $this->redirect(array('controller'=>'homes','action'=>'step_four'));
        }
        else
        {
            $this->setFlashMsg('Please Provide Valid Information','message-box ok');
        }
    }
}

here is the model function uploadfiles()

public function uploadfiles()
    {
    if(isset($_FILES['fileupload']))
    {
        $errors= array();
        foreach($_FILES['fileupload']['tmp_name'] as $key => $tmp_name )
        {
            print_r($_FILES);
            exit;
            $file_name = $key.$_FILES['fileupload']['name'][$key];
            $file_size =$_FILES['fileupload']['size'][$key];
            $file_tmp =$_FILES['fileupload']['tmp_name'][$key];
            $file_type=$_FILES['fileupload']['type'][$key]; 
            if($file_size > 2097152)
            {
                $errors[]='File size must be less than 2 MB';
            }   
            $upload_dir = ROOT;
            $desired_dir="/uploads/";
            if(empty($errors)==true)
            {
                if(is_dir($desired_dir)==false)
                {
                    mkdir("$desired_dir", 0700); // Create directory if it does not exist
                }
            if(is_dir("$desired_dir/".$file_name)==false)
            {
                //$file_path=$upload_dir."$desired_dir/".$file_name;
                move_uploaded_file($file_tmp,$upload_dir."$desired_dir/".$file_name);
            }
            else
            {                                           // rename the file if another one exist
                $file_path=$upload_dir."$desired_dir/".$file_name.time();
                rename($file_tmp,$file_path) ;              
            }           
        }
        else
        {
            print_r($errors);
        }
    }
    if(empty($error))
    {
            //echo "Success"; exit;
            return true;
    }
    return false;
}

What am I missing here?

Mark Schultheiss
  • 32,614
  • 12
  • 69
  • 100
kiran kumar
  • 29
  • 1
  • 6
  • Your actual `uploading` function perhaps? `move_uploaded_file` ;-) and the fact that your Ajax has no URL set to your PHP uploading code. **Q:** Where did you get those codes from? I doubt you're showing us everything here. – Funk Forty Niner Jul 23 '13 at 16:54
  • i updated the question -Fred – kiran kumar Jul 23 '13 at 17:03
  • Thank you Kiran. Now, can you explain this line for me? `$upload_dir = ROOT;` - I think this is proprietary to CodeIgniter, am I right? – Funk Forty Niner Jul 23 '13 at 17:03
  • ROOT is nothing but the root directory.. I have defined as a global variable. – kiran kumar Jul 23 '13 at 17:06
  • You mentioned `$_FILES Array`. Are you allowing for multiple uploads? – Funk Forty Niner Jul 23 '13 at 17:08
  • first i was trying with multiple files but then i switched to single file upload to test the program..if i access this 3rd page directly and if i upload one file then the files are uploading but when i dynamically show the form using ajax then if it wont upload the file, it doest works – – kiran kumar Jul 23 '13 at 17:10
  • Usually and in Pure PHP, when uploading multiple files, they are set in an array, where the name in the form for example yours `name="fileupload"` would have added brackets as such `name="fileupload[]"`. That's why I asked about the "array". – Funk Forty Niner Jul 23 '13 at 17:12
  • Fred:- i have added the fileupload[] before to use as multiple file uploads... i think its because of enctype multipart/form-data, the ajax call is not creating the enctype attribute – kiran kumar Jul 23 '13 at 17:14
  • Hm, not sure about the `enctype` being at fault, but won't leave it out of the equation. I'm starting to question `if(isset($_POST['post'])){`. I see it's associated with ``. I've seen another case a few days ago, where if it was a "hidden" value, the upload wouldn't work. Why don't you try `if(isset($_POST['submit'])){` just to "test" it out and name your ` ` to `` – Funk Forty Niner Jul 23 '13 at 17:22
  • k wait i'll give a try – kiran kumar Jul 23 '13 at 17:24
  • OOoohhhhhhhh **Wait a minute**, I just noticed something. You're using **"sessions"**. `session_start();` is missing from your "posted" code. If you don't have it in there, then that must be on TOP of every `.php` file. – Funk Forty Niner Jul 23 '13 at 17:27
  • i have started the session at top in controller.. thats not the issue – kiran kumar Jul 23 '13 at 17:30
  • Darn it, I was sure that was it. And my other suggestion didn't work, I take it.? – Funk Forty Niner Jul 23 '13 at 17:31
  • And adding a `name` to `` as in `` didn't work neither? – Funk Forty Niner Jul 23 '13 at 17:38
  • no buddy... No luck again – kiran kumar Jul 23 '13 at 17:42
  • I am completely **"baffled"**. Nothing in your `.htaccess` that would play tricks on you neither? I've seen that happen before also. – Funk Forty Niner Jul 23 '13 at 17:45
  • me completely baffled from 2 days – kiran kumar Jul 23 '13 at 17:47
  • What about in your `foreach...`. I noticed `print_r($_FILES); exit;` - Doesn't `exit;` STOP execution? – Funk Forty Niner Jul 23 '13 at 17:47
  • ya its just to echo the uploaded files.. it shows empty array when i upload the file... I Kept for testing purpose – kiran kumar Jul 23 '13 at 17:49
  • Ok. Another thing `$desired_dir="/uploads/";` You have a forward slash at the end. And in `$file_path=$upload_dir."$desired_dir/"` you also have another forward slash. I doubt it's the problem, but do you think otherwise? And in a few other areas also. – Funk Forty Niner Jul 23 '13 at 17:52
  • Try removing the slash at the end of `/uploads/` to read as `/uploads` maybe? – Funk Forty Niner Jul 23 '13 at 17:55
  • Fred my friend, thats my root upload folder, its working fine if i access the 3rd step page directly.. the problem is the form wizrd, it has 4 steps, one form in each page, if i click next in one page then the next form is loaded using the ajax call which i shown above – kiran kumar Jul 23 '13 at 17:57
  • So you think the problem is inside your `uploadfiles()` class model or in `step_three()`? – Funk Forty Niner Jul 23 '13 at 18:00
  • no... the problem is with ajax call. the uploadfiles() is working fine when i access the page directly.. i think its due to enctype – kiran kumar Jul 23 '13 at 18:01
  • if u get any solution the pls PM me at kirant043@gmail.com... And Ha Special thanks for putting your efforts... I'll be waiting ur reply – kiran kumar Jul 23 '13 at 18:06
  • You have `'action'=>'step_three_ajax'` in your `action`, yet you have `else if('step-three'==$(thisObj).attr('id')){` and `function step_three(){`. Something doesn't seem to match here, nor do I see another call to `step_three_ajax`. – Funk Forty Niner Jul 23 '13 at 18:07
  • You're welcome Kiran. Yet, did you have a look at my comment, just above this one? – Funk Forty Niner Jul 23 '13 at 18:11
  • step_three() functions is for validation of input fields.. it returns true after all inputs have correct values – kiran kumar Jul 24 '13 at 02:02
  • But you have the action set as `'action'=>'step_three_ajax'`, isn't that supposed to be `'action'=>'step_three'`? – Funk Forty Niner Jul 24 '13 at 12:56
  • you see here else if('step-three'==$(thisObj).attr('id')){ submit = stepThree(); this is where the validations goes and returns true and it goes step_three_ajax – kiran kumar Jul 26 '13 at 08:45
  • You have `'action'=>'step_three'` and `if('step-three'`. Notice the **"dash"** (-) in `step-three` in your `if...` instead of an **underscore** ( _ ) in your `action'=>...`? – Funk Forty Niner Jul 26 '13 at 14:54
  • @MarkScultheiss, I don't think this is a duplicate. OP mentioned he has success when accessing the upload page directly. It is only a problem when loading forms via ajax... – Jason J. Nathan Jul 27 '13 at 18:10
  • @jasonnathan u r right... I found that file upload wont works in ajax – kiran kumar Jul 28 '13 at 07:49

3 Answers3

1

Try this.

$('.ajxfrm').live('submit',function(){
        var thisObj = $(this),
            submit = true;

        if('step-two'== thisObj.attr('id')){
            submit = stepTwo();
        }else if('step-three'== thisObj.attr('id')){
            submit = stepThree();
        }
        if(submit){
            $.ajax({
              type: "POST",
              data: thisObj.serialize(),
              url: thisObj.attr('action'),
              beforeSend: function(){
                 showOverLayer();
              },
              success: function(data){
                 thisObj.parent("#content").empty().html(data).hide().fadeIn(function(){
                     setBlocks();
                     setLiClick();
                     hideOverLayer();
                 });
                 changeCalNaviHref();
              }
            });
        }
    return false;
});

Can you show me one console.log(data) on the success method?

Thanks

Rafael Gomes
  • 112
  • 1
  • 9
  • Sorry buddy... it didnt worked... if i access this 3rd page directly and if i upload one file then the files are uploading but when i dynamically show the form using ajax then if it wont upload the file, it doest works – kiran kumar Jul 23 '13 at 17:09
  • I'm not developing here, but...when you return false in a submit form, don't you blocking to send? – Rafael Gomes Jul 23 '13 at 17:20
  • @RafaelGomes, `return false` just prevents the default submit action of the form. These days though, we use `event.preventDefault()` – Jason J. Nathan Jul 26 '13 at 07:05
  • Thanks @jasonnathan, you're completely right! I got confused for a minute. :) – Rafael Gomes Jul 29 '13 at 20:26
0

Two total long shots here:

1) You mentioned that your sessioning code is "up top". Are you using something like session_regenerate_id there? That will mess with parallel uploads.

or

2) Take a look at whether your session file is locked when other sessions are coming in. google an article or two on session_write_close().

But its more likely to be #1.

Mark Schultheiss
  • 32,614
  • 12
  • 69
  • 100
Mark Kasson
  • 1,600
  • 1
  • 15
  • 28
  • no i'm not using sessions_regenerate_id here... IF i echo all the sessions then its showing the correct values – kiran kumar Jul 23 '13 at 17:55
  • If its getting lost in ajax, have you viewed the interaction with either Fiddler or Firebug? See what's posted over to the server and if its different with one file versus multiple files. – Mark Kasson Jul 23 '13 at 19:28
  • No i didnt checked... Actually I dnt know how to use the Fiddler – kiran kumar Jul 24 '13 at 06:49
  • I find Firebug slightly easier to use, but its a Firefox add in. If you're using something else, use Fiddler. In Firebug, under Net, check the POST to see what is being sent over with one and multiple files. – Mark Kasson Jul 24 '13 at 13:10
0

You cannot send files using 'old' AJAX (not this way).

If you want to send files, take a look at XMLHttpRequest2. Pretty good tutorial is here - http://www.html5rocks.com/en/tutorials/file/xhr2/

Andreyco
  • 22,476
  • 5
  • 61
  • 65