multiple files upload

See all posts Reply

multiple files upload new!
by Sergio, 16 years, 9 months ago
Hello,

I'm trying to implement this script to another that I'm using for a long time. That script has option for uploading photos but it can't optimize them and make thumbnails. Now, I want implement this code to that script.
The original part of PHP script for uploading before adding new code looks like this:

include_once C_PATH.'/classes/upload.class.php';
$time = time();
for($p = 0; $p <= 2; $p++) {
  $file = 'file'.$p;
  $k = $p+1;
  if (!empty($HTTP_POST_FILES[$file]['name']))   {
    if (!C_IMG_ERR)     {
      // If Unavailable image upload errors with UIN
      $dir = date("mY", $time);
      $slash = "/";
      if (!file_exists(C_PATH.'/members/uploads/'.$dir))
        {
        umask(0);
        mkdir (C_PATH."/members/uploads/".$dir, 0777);
      }
    } else $dir = $slash = "";
    $fb = date("dHis", $time);
    $fe = rand(0, 999);
    $fn = $fb."-".$fe;
    $intpic = $dir.$slash.$fn.'.';
    $u = new Upload($file, C_MAXSZ, C_MAXWD, C_MAXHG, C_PATH.'/members/uploads/'.$intpic);
    if (!$u->do_upload()) printm($u->getErrors());
    $mpic[$k] = ", pic".$k."='".$intpic.$u->getType()."'";
  }
}
 
/////////////
$last_id = $_SESSION['m'];
$usr = ((C_ID) || (!isset($username))) ? '' :
 "username='".$username."',";
mysql_query("UPDATE ".C_MYSQL_MEMBERS." SET ".$usr."fname='".$fname."',lname='".$lname."',birthday='".$year."-".$month."-".$day."',gender='".$gender."',
  purposes='".$purpose."',country='".$country."',email='".$email."',url='".$url."',
  icq='".$icq."',aim='".$aim."',phone='".$phone."',city='".$city."',marstat='".$marstat."',child='".$child."',height='".$height."',weight='".$weight."',hcolor='".$hcolor."',ecolor='".$ecolor."',etnicity='".$etnicity."',religion='".$religion."',smoke='".$smoke."',drink='".$drink."',education='".$education."',job='".$job."',hobby='".$hobby."',descr='".$descr."',sgender='".$sgender."',setnicity='".$setnicity."',sreligion='".$sreligion."',agef='".$agef."',aget='".$aget."',heightf='".$heightf."',heightt='".$heightt."',weightf='".$weightf."',weightt='".$weightt."',horo='".horo($month, $day)."',editdate=NOW(''),ip='".ip2int(ip())."',status='".$cst."' ".$mpic[1].$mpic[2].$mpic[3]." WHERE id='".$last_id."'") or die(mysql_error());

Problem is that this script is using for changing users profile. That means that there are already uploaded photos and recorded in database and now, when I add your code and use your class it overwrites those records in database and makes empty records in database for all fields that are empty in upload process.

For example, some user successfully register them self and PHP records all data in DB with 3 photos. After that, the same user want to change these pics and instead of second photos in his profile he want to put another second pics. When he try to do that the result is there is no ald photos in his profile and the new one that he want to upload is on first position.

How can I solve this problem.

Thanks a lot in advance.


Regards.Reply
Re: multiple files upload new!
by colin, 16 years, 9 months ago
I am afraid that goes beyond the scope of the class itself. The class only deals with the upload, but not with any updates you may do in your database.

Try to print the $_FILES array, so that you can see which pictures have been uploaded or not, and then modify your SQL statement accordingly.
echo print_r($_FILES, 1);
Reply
Re: multiple files upload new!
by Sergio, 16 years, 9 months ago
Upload working just fine but the problem is with every new upload process which include empty input file fields that overwrites existing non empty mysql input.

Can the problem be related with my_field[] array?Reply
Re: multiple files upload new!
by colin, 16 years, 9 months ago
If you have some empty fields, simply don't include them in your SQL query.

See the FAQ, the question called What about multiple uploads? to see how to deal with multiples uploads. When you parse $_FILES, you can check whether a file has been uploaded or not.Reply
Re: multiple files upload new!
by Sergio, 16 years, 9 months ago
I already saw that question and include that in code. Here is the code that I'm trying to making useful:

include_once '../classes/class.upload.php';
$time = time();
for($p = 0; $p <= 2; $p++) {
  $file = 'file'.$p;
  $k = $p+1;
  if (!empty($HTTP_POST_FILES['my_field']['name'][$p])) {
    if (!C_IMG_ERR) {
      // If Unavailable image upload errors with UIN
      $dir = date("mY", $time);
      $slash = "/";
    } else $dir = $slash = "";
    $fb = date("dHis", $time);
    $fe = rand(0, 999);
    $fn = $fb."-".$fe;

    $handle = new upload($_FILES['my_field']);
    $this_upload = array();

    $dir = date("mY", $time);$slash="/";
    $fb=date("dHis",$time);$fe=rand(0,999);$fn =$fb."-".$fe;
    $intpic = $fn.'.';
    $handle->jpeg_quality = 70;
    $handle->image_watermark = 'watermark.png';
    $handle->image_watermark_position = 'B';
    $handle->file_new_name_body = $intpic;
    $handle->Process("uploads/$dir");

    if ($handle->uploaded) {
      if ($handle->processed) {
        $this_upload['large'] = $handle->file_dst_name;
      }
    } 

    $handle->image_resize            = true;
    $handle->image_ratio_y           = true;
    $handle->image_x                 = 80;
    $handle->file_new_name_body = $intpic;
    $handle->Process("uploads/tmb/$dir");
  
    if ($handle->processed) {
      // store the small image filename  
      $this_upload['small'] = $handle->file_dst_name;
      $handle->clean();
    } 
  
    // add this set of pictures to the main array
    $uploaded[] = $this_upload;
  }  
  if ($uploaded[0]['large'] !='') $d1=$dir.'/';
  if ($uploaded[1]['large'] !='') $d2=$dir.'/';
  if ($uploaded[2]['large'] !='') $d3=$dir.'/';

  $mpic[1]=", pic1='".$d1.$uploaded[0]['large']."'";
  $mpic[2]=", pic2='".$d2.$uploaded[1]['large']."'";
  $mpic[3]=", pic3='".$d3.$uploaded[2]['large']."'";
}


Input file field has name "my_field[]"Reply
Re: multiple files upload new!
by colin, 16 years, 9 months ago
Read the FAQ again. If you do multiple uploads, you have to change the $_FILES array.

$files = array();
foreach ($_FILES['my_field'] as $k => $l) {
 foreach ($l as $i => $v) {
 if (!array_key_exists($i, $files)) 
   $files[$i] = array();
   $files[$i][$k] = $v;
 }
} 

Then you can use $files rather than $_FILES in your code. Note that you can trim out all non-uploaded images in the code above.Reply
Re: multiple files upload new!
by Sergio, 16 years, 9 months ago
How can I trim all non uploaded images?

With this code:
for($p = 0; $p <= 2; $p++) {  
  $file = 'file'.$p;  $k = $p+1;  
  if (!empty($HTTP_POST_FILES['my_field']['name'][$p])) {
  ...

Or there is some better solutions for that?Reply
Re: multiple files upload new!
by colin, 16 years, 9 months ago
If you have multiple upload fields, they will have the same name, right?

So assuming that you have three of these upload fields, called my_field[], and that the user enters a file for the first and third field only, $_FILES will be as following:
Array
  [my_field] => Array
    [name] => Array
      [0] => P1040124.JPG
      [1] => 
      [2] => P1040281.JPG
    [type] => Array
      [0] => image/jpeg
      [1] => 
      [2] => image/jpeg
    [tmp_name] => Array
      [0] => /tmp/php0bMcTr
      [1] => 
      [2] => /tmp/phpxf9Rr5
    [error] => Array
      [0] => 0
      [1] => 4
      [2] => 0
    [size] => Array
      [0] => 2959714
      [1] => 0
      [2] => 2329004

We need to re-organize the array for the class, with.
$files = array();
foreach ($_FILES['my_field'] as $k => $l) {
 foreach ($l as $i => $v) {
 if (!array_key_exists($i, $files)) 
   $files[$i] = array();
   $files[$i][$k] = $v;
 }
}

So we have now in $files:
Array
  [0] => Array
    [name] => P1040124.JPG
    [type] => image/jpeg
    [tmp_name] => /tmp/php7aqJYX
    [error] => 0
    [size] => 2959714
  [1] => Array
    [name] => 
    [type] => 
    [tmp_name] => 
    [error] => 4
    [size] => 0
  [2] => Array
    [name] => P1040281.JPG
    [type] => image/jpeg
    [tmp_name] => /tmp/phpKet10G
    [error] => 0
    [size] => 2329004

So we need to modify our loop so that $files doesn't include the second entry in the array, which is for the non-uploaded file. So the loop becomes:
$files = array();
foreach ($_FILES['my_field'] as $k => $l) {
  foreach ($l as $i => $v) {
    if (!array_key_exists($i, $files)) 
      $files[$i] = array();
    $files[$i][$k] = $v;
  }
}
// we now remove invalid entries for non-uploaded images
foreach ($files as $k => $v) {
  if ($v['error'] != 0) unset($files[$k]);
}

So now you can feed $files into class.upload.php, for instance doing as following:
foreach (array_keys($files) as $k) {
  $handle = new upload($files[$k]);
  // process your upload here
}
Reply
Re: multiple files upload new!
by Irineu Jr, 15 years, 6 months ago
Thanks... thats exacly what i need...Reply
Re: multiple files upload new!
by Sergio, 16 years, 9 months ago
I did everything as you said but I get same result each time. The already uploaded images and recorded in database been erased if those input fields are empty in new upload process.

For example, I upload images for specific members on first and third input fields and successfully recorded in database (in DB columns pic1 and pic3 now got records and pic2 are empty) if I next time try to upload new image at field two, pic1 and pic3 will be erased and pic2 will be recorded for the same members.

As far as understand script send an empty value that overwrites existing records in database for pic1 and pic3. How can I escape this and keep existing DB record if first and third fields are empty?

This is the code that I creat by your instruction:

include_once '../classes/class.upload.php';

$files = array();
foreach ($_FILES['my_field'] as $k => $l) {  
  foreach ($l as $i => $v) {    
    if (!array_key_exists($i, $files))       
      $files[$i] = array();    
    $files[$i][$k] = $v;  
  }
}
// we now remove invalid entries for non-uploaded images
foreach ($files as $k => $v) {  
  if ($v['error'] != 0) unset($files[$k]);
}

$uploaded = array();
  
foreach (array_keys($files) as $k) {  
  $handle = new upload($files[$k]);
  $this_upload = array();
   
  $time = time();
  $dir = date("mY", $time);$slash="/";
  $fb=date("dHis",$time);$fe=rand(0,999);
  $fn =$fb."-".$fe;
  $intpic = $fn.'.';
  $handle->jpeg_quality = 70;
  $handle->image_watermark = 'watermark.png';
  $handle->image_watermark_position = 'B';
  $handle->file_new_name_body = $intpic;
  $handle->Process("uploads/$dir");
  
  if ($handle->uploaded) {
    if ($handle->processed) {
      $this_upload['large'] = $handle->file_dst_name;
    }
  } 
  $handle->image_resize            = true;
  $handle->image_ratio_y           = true;
  $handle->image_x                 = 80;
  $handle->file_new_name_body = $intpic;
  $handle->Process("uploads/tmb/$dir");
    
  if ($handle->processed) {
    // store the small image filename  
    $this_upload['small'] = $handle->file_dst_name;
    $handle->clean();
  } 
    
  // add this set of pictures to the main array
  $uploaded[] = $this_upload;
}
  
$msc0 = (($uploaded[0]['large'] !='')) ? $dir.'/' : '';
$msc1 = (($uploaded[1]['large'] !='')) ? $dir.'/' : '';
$msc2 = (($uploaded[2]['large'] !='')) ? $dir.'/' : '';

$mpic[1]=", pic1='".$msc0.$uploaded[0]['large']."'";
$mpic[2]=", pic2='".$msc1.$uploaded[1]['large']."'";
$mpic[3]=", pic3='".$msc2.$uploaded[2]['large']."'";

$last_id = $_SESSION['m'];
$usr = ((C_ID) || (!isset($username))) ? '' :
  "username='".$username."',";
mysql_query("UPDATE ".C_MYSQL_MEMBERS." SET ".$usr."fname='".
  $fname."',lname='".$lname."',birthday='".$year."-".
  $month."-".$day."',gender='".$gender."', purposes='".
  $purpose."',country='".$country."',email='".
  $email."',url='".$url."', icq='".$icq."',aim='".
  $aim."',phone='".$phone."',city='".$city."',marstat='".
  $marstat."',child='".$child."',height='".
  $height."',weight='".$weight."',hcolor='".
  $hcolor."',ecolor='".$ecolor."',etnicity='".
  $etnicity."',religion='".$religion."',smoke='".
  $smoke."',drink='".$drink."',education='".
  $education."',job='".$job."',hobby='".$hobby."',descr='".
  $descr."',sgender='".$sgender."',setnicity='".
  $setnicity."',sreligion='".$sreligion."',agef='".
  $agef."',aget='".$aget."',heightf='".$heightf."',heightt='".
  $heightt."',weightf='".$weightf."',weightt='".
  $weightt."',horo='".horo($month, $day).
  "',editdate=(now('')+INTERVAL 7 HOUR),ip='".ip2int(ip())
  ."',status='".$cst."' ".$mpic[1].$mpic[2].$mpic[3]
  ."  WHERE id='".$last_id."'") or die(mysql_error());
Reply
Re: multiple files upload new!
by colin, 16 years, 9 months ago
This is not a problem with the class! Please check your SQL query.

Even if some images are not uploaded, you are still updating the database! You always update the three image fields in your query.

This code below:
$mpic[1]=", pic1='".$msc0.$uploaded[0]['large']."'";
$mpic[2]=", pic2='".$msc1.$uploaded[1]['large']."'";
$mpic[3]=", pic3='".$msc2.$uploaded[2]['large']."'";
Should be something like:
if (array_key_exists(0, $uploaded)) 
  $mpic[1]=", pic1='".$msc0.$uploaded[0]['large']."'";
if (array_key_exists(1, $uploaded)) 
  $mpic[2]=", pic2='".$msc1.$uploaded[1]['large']."'";
if (array_key_exists(2, $uploaded)) 
  $mpic[3]=", pic3='".$msc2.$uploaded[2]['large']."'";
So that you are updating ONLY the fields which have an image uploaded.

Note that you will also have to change this line
$uploaded[] = $this_upload;
into something like:
$n++; 
$uploaded[$n] = $this_upload;
so that each picture from $_FILES has proper key.

Please contact me privately should you want more information. This is a basic PHP/MySQL problem, and has nothing to do with this forum.Reply