I'm using array function to point and set up multiple directories in the following file uploader code:

<?php
$directory_a = 'site.com/directory-x/';     
$directory_b = 'subsite-a.site.com/directory-y/'; $directory_c = 'subsite-b.site.com/directory-z/'; $dir = array( "$directory_a", "$directory_b", "$directory_c"); /// Defining the directories in an aray foreach ($dir as $directory){ $max_size = 1024; $allowtype = array('bmp', 'gif', 'jpg', 'jpeg'); $rezultat = array(); if (isset($_FILES['file_upload'])) { for($f=0; $f<count($_FILES['file_upload']['name']); $f++) { $nume_f = $_FILES['file_upload']['name'][$f]; if (strlen($nume_f)>3) { $type = end(explode('.', strtolower($nume_f))); if (in_array($type, $allowtype)) { if ($_FILES['file_upload']['size'][$f]<=$max_size*1028) { if ($_FILES['file_upload']['error'][$f]==0) { $thefile = $directory . '/'. $nume_f; /// Setting up multiple directories for uploading file if (!move_uploaded_file ($_FILES['file_upload']['tmp_name'][$f], $thefile)) { $result[$f] = 'The file '. $nume_f. 'Unable to copy, try again'; } else { $result[$f] = ''.$nume_f.''; } } } else { $result[$f] = 'The file '. $nume_f. ' Unpermitted size, <i>'. $max_size. 'KB</i>'; } } else { $result[$f] = 'The file '. $nume_f. 'Invalid file type'; } } } $_SESSION['result'] = implode($result); header('Location: '.basename($_SERVER['PHP_SELF']).'?file=uploaded'); } if (isset($_GET['file']) && isset($_SESSION['result'])) { echo 'Uploaded File: '. $_SESSION['result']; unset($_SESSION['result']); } else { echo "Select file to upload"; } } ?>
<form id="uploadform" action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post" enctype="multipart/form-data">
<input name="upload_file[]" type="file" class="upload_file" size="50" />
<input type="submit" value="Upload" id="submit" />
</form>

But I'm receiving "Unable to copy, try again" message when submit the form.

Where and how I'm doing the mistake or should I use explode function in this case?

Any idea?

    $rezultat = array();

    should be read as

    $rezult = array();

    in the above php code.

                  move_uploaded_file ($_FILES['file_upload']['tmp_name'][$f], $thefile) { 

      Does what it says; it moves the file. So after the files have been moved into the first directory they're not in the temp directory any more and the second and subsequent directories miss out.

      I suggest you use [man]is_uploaded_file[/man] to verify that [font=monospace]$_FILES['file_upload']['tmp_name'][$f][/font] is an uploaded file, and then simply [man]copy[/man] into the necessary directories.

        Weedpacket, thanks.

        So, can I define & set the directories like,

        ///Define Directories
        $directory_a = 'site.com/directory-x/';     
        $directory_b = 'subsite-a.site.com/directory-y/'; $directory_c = 'subsite-b.site.com/directory-z/'; /// Set Directories $firstdir = $site.com/directory-x/ . '/'. $nume_f;
        $seconddir = subsite-a.site.com/directory-y/ . '/'. $nume_f;
        $thirddir = subsite-b.site.com/directory-x/ . '/'. $nume_f;
        $alldir = copy($firstdir, $seconddir, $thirddir); ///Check if file moves to all the directories if (!move_uploaded_file ($_FILES['file_upload']['tmp_name'][$f], $alldir)) { $result[$f] = 'The file '. $nume_f. 'Unable to copy, try again'; }else{.....
          polarexpress;11041209 wrote:

          The file is copied & move from tmp directory

          The keywords here are "MOVED" and "FROM"

          Initial contents of directory /tmp

          .
          ..
          the-file
          

          Then, after the first call to

          move_uploaded_file('the-file', 'dir-one/the-file');
          

          The contents of directory /tmp are now

          .
          ..
          

          because the file was MOVED FROM /tmp to some other place.

          The solution is to either
          1. move_uploadedfile('the-file', 'dir-one/the-file');
          2. copy('dir-one/the-file', 'dir-N/the-file');
          3. repeat 2. for each remaining directory N

          Or to simply use copy from the beginning. But as the documentation states, [man]move_uploaded_file[/man] does an additional check before moving the file.

          This function checks to ensure that the file designated by filename is a valid upload file (meaning that it was uploaded via PHP's HTTP POST upload mechanism). If the file is valid, it will be moved to the filename given by destination.

          Therefor, I'd say you should go with move_uploaded_file, followed by copy from the new location.

          Moreover, I'd also change the structure of your code to minimize the size of your directory loop block, because it is not placed in a logically sound place and also leads to unnecessary work being done. Not very time consuming work, but unnecessary none the less.

          The code from your initial post

          foreach ($dir as $directory){
              $max_size = 1024;
              $allowtype = array('bmp', 'gif', 'jpg', 'jpeg');
              $rezultat = array();
          
          if (isset($_FILES['file_upload'])) {
              # do stuff…
          }
          }
          

          Let's say no file was uploaded. I.e. $_FILES['uploaded_file'] is not set, and you have 100 directories you want into which you wish to copy uploaded files. You will then check if a file was uploaded 100 times, even though you should know better after the first check. Assigning 1024 to $max_size is equally pointless.
          But perhaps more importantly is readability. If the only code inside the foreach($dir as $directory) is moving / copying a file into that directory, it is readily obvious what is done with/to each directory. Otherwise you have to read through 25-or-so lines to check if a directory is perhaps deleted, created etc in those 25 lines…

          Suggested structure changes.
          Code is not tested. Code is not intended to be ready for use. It is just a means to suggest a different structure.

          # Let this be the very first line, because this check singlehandedly decides
          # if anything needs to be done
          if (isset($_FILES['file_upload'])) {
              # all of these are needed for all uploaded files. but unless you have at least one
              # uploaded file, there is no need defining these (outside the first if-check)
              $directory_a = 'site.com/directory-x/';
              $directory_b = 'subsite-a.site.com/directory-y/';
              $directory_c = 'subsite-b.site.com/directory-z/';
          
          # skip the string interpolation in "$var". Instead use $var
          $dir = array( $directory_a, $directory_b, $directory_c);  /// Defining the directories in an aray
          
          $max_size = 1024;
          # do note that the presence of these file extension in the file name
          # says nothing about the file contents. It's just a good convention to
          # name your files that way to indicate what they are. But they may still
          # contain anything.
          $allowtype = array('bmp', 'gif', 'jpg', 'jpeg');
          # inspecting the file contents to determine the contents of the file contents is far better
          $exif_ok = [IMAGETYPE_GIF => '.gif', IMAGETYPE_JPEG => '.jpg', IMAGETYPE_PNG => '.png', IMAGETYPE_BMP => '.bmp'];
          
          $result = array();
          
          for ($i = 0; $i < count($_FILES['file_upload']['error']); $i += 1) {
              # Check for error / success as the very first thing. If there was an error,
              # no more work needs to be done
              if ($_FILES['file_upload']['error'][$i] === 0) {
                  # additional checks for valid file type goes here
                  $type = exif_imagetype($_FILES['file_upload']['tmp_name']);
                  if (isset($exif_ok[$type])) {
                      $filename = $_FILES['file_upload']['name'];
                      # if the filename extension does not match the image type, you may of course add it
                      if (substr($filename, -4) != $exif_ok[$type]) {
                          $filename .= $exif_ok[$type];
                      }
          
                      # 1. move uploaded file to first directory - false returned on failure
                      # Do note that the filename you use as target may already exist.
                      # It will be overwritten in that case.
                      $copyBase = $dir[0] . '/' . $_FILES['file_upload']['name'][$i];
                      if (move_uploaded_file($_FILES['file_upload']['tmp_name'][$i], $copyBase)) {
                          # 2. Copy to other directories
                          # Now only the work actually relevant in regards to each directory is found
                          # inside the loop over your directories. And there is only one line of code
                          # you have to inspect in order to find out what is done with each directory.
                          for ($dirIndex = 1; $dirIndex < count($dir); $dirIndex += 1) {
                              copy($copyBase, $dir[$dirIndex] . '/' . $_FILES['file_upload']['name'][$i]);
                          }
                      }
                  }
              }
          }
          }
          

          And as a final note. If the directories are all mounted on the same web server, you might as well just add symlinks from directories 2 and 3 to directory 1.

          # using site.com/directory-x/ as base directory
          # create symlinks to this directory from where you need access to the same files
          $ ln -s subsite-a.site.com/directory-y/ site.com/directory-x/
          $ ln -s subsite-b.site.com/directory-z/ site.com/directory-x/
          

          Now both directory-y and directory-z are symbolic links to directory-x. When you copy a file-A to directory-x, that file is also reachable through both directory-y/file-A and directory-z/file-A. But there is still just one file, and it is located in directory-x.
          Doing this means you only need to move_uploaded_file to directory-x and you are done.

            Thanks for your precise guideline johanafm.

            I guess something is going wrong in the following code. It can't move the file to base directory and the copy it to the other directories respectively.

                      [code=php]  ......{
            
                        # 1. move uploaded file to first directory - false returned on failure
                        # Do note that the filename you use as target may already exist.
                        # It will be overwritten in that case.
                        $copyBase = $dir[0] . '/' . $_FILES['file_upload']['name'][$i];
                        if (move_uploaded_file($_FILES['file_upload']['tmp_name'][$i], $copyBase)) {
                            # 2. Copy to other directories
                            # Now only the work actually relevant in regards to each directory is found
                            # inside the loop over your directories. And there is only one line of code
                            # you have to inspect in order to find out what is done with each directory.
                            for ($dirIndex = 1; $dirIndex < count($dir); $dirIndex += 1) {
                                copy($copyBase, $dir[$dirIndex] . '/' . $_FILES['file_upload']['name'][$i]);
                            }
                        }[/code]

              If you are merging it with your original code, do note that you are using $f as index into the files array, while my example uses $i.

                johanafm, thanks,

                If I avoid array function, it only requires a single line of code along with copy(); function to upload the file on each additional directory using my existing code.

                I was confused as the following code doesn't force to move_uploaded_file directly rather it was bypassed to give an output in case file isn't moved from tmp to destination folder but in fact the move_uploaded_file function performs it's task in the gap cleverly.

                if (!move_uploaded_file ($_FILES['file_upload']['tmp_name'][$f], $thefile)) {
                              $result[$f] = 'The file '. $nume_f. 'Unable to copy, try again';
                            } 

                it could be like,

                if (move_uploaded_file ($_FILES['file_upload']['tmp_name'][$f], $thefile)) {
                              $result[$f] = 'The file '. $nume_f. 'Moved to destination folder';
                            } 
                

                Anyway, thanks again for your support.

                  Write a Reply...