After many frustrating hours and web searching I cannot figure out why the move_uploaded_file is appending the names of already already created files to the name of new files. As you will be able to tell from my code I an pretty new to PHP. However, I have a pretty large CSS form with the capability to upload 8 separate files (<input type="file" name="File1"/> name of each file from File1 to File 8.)

I am using the following code to upload the files to my pre-defined folder. The client names of the files that are being uploaded are (1.doc, 2.doc and 3.doc). The upload seems to work, however the files created on the server are named 1.doc, 1.doc2.doc and 1.doc2.doc3.doc

My problem is that I do not fully understand the use of the code and what [name] and [tmp_name actually do. Can anyone help?

php code...

$target_path = "../Filestore/";
$target_path = $target_path . basename( $_FILES);
move_uploaded_file($_FILES, $target_path);
$target_path = $target_path . basename( $_FILES);
move_uploaded_file($_FILES, $target_path);
$target_path = $target_path . basename( $_FILES);
move_uploaded_file($_FILES, $target_path);

Dani AI

Generated

correctly pinpointed the immediate cause — reusing the same $target_path variable produced the cumulative filename concatenation that saw. Below are practical, security-minded steps to make the whole delete/upload/zip/email workflow reliable, plus a compact example that handles multiple file fields, validates uploads, and avoids name collisions.

Ensure the HTML form uses enctype="multipart/form-data". For each file field check the upload error code (UPLOAD_ERR_OK), confirm the temporary file is a real uploaded file with is_uploaded_file(), and test the boolean return from move_uploaded_file(). Do not rely on the client-supplied name for storage: sanitize the base name, or better, generate a new unique filename (uniqid or a database id) and store the original name as metadata. Make sure the target directory exists and is writable by the webserver user (prefer chown/chgrp to 0777) and prefer storing uploads outside the webroot or deny direct access with server rules.

Example loop (handles File1..File8, generates safe unique names and checks errors):

$targetDir = __DIR__ . '/../Filestore/';
$fields = array('File1','File2','File3','File4','File5','File6','File7','File8');

foreach ($fields as $f) {
    if (empty($_FILES[$f]) || $_FILES[$f]['error'] !== UPLOAD_ERR_OK) continue;
    if (!is_uploaded_file($_FILES[$f]['tmp_name'])) continue;
    $base = pathinfo($_FILES[$f]['name'], PATHINFO_FILENAME);
    $ext  = pathinfo($_FILES[$f]['name'], PATHINFO_EXTENSION);
    $safe = preg_replace('/[^A-Za-z0-9_\-]/', '_', $base);
    $target = $targetDir . uniqid($safe . '_') . ($ext ? '.' . $ext : '');
    if (!move_uploaded_file($_FILES[$f]['tmp_name'], $target)) {
        error_log("Upload move failed for field $f");
    }
}

For zipping and emailing: use ZipArchive (close the archive before attaching), keep stored filenames predictable and safe inside the zip, and use a proven mail library (PHPMailer) for attachments. Always remove temporary files after the email is sent. Finally, verify php.ini limits (upload_max_filesize, post_max_size, max_file_uploads) if multiple or large files are involved.

Recommended Answers

All 2 Replies

Hi Thorby68,

The code you posted was:

$target_path = "../Filestore/";
$target_path = $target_path . basename( $_FILES['File1']['name']);
move_uploaded_file($_FILES['File1']['tmp_name'], $target_path);
$target_path = $target_path . basename( $_FILES['File2']['name']);
move_uploaded_file($_FILES['File2']['tmp_name'], $target_path);
$target_path = $target_path . basename( $_FILES['File3']['name']);
move_uploaded_file($_FILES['File3']['tmp_name'], $target_path);

To take your questions one at a time...
$_FILES holds the original name of the file when uploaded.

$_FILES holds the temporary name assigned to the file by your webserver. This variable will need to be used when referencing the file until you've moved it from the temp directory to its permanent home on your webserver.

The reason you're getting concatenated filenames is because you're concatenating the variable $target_path.

Try the following code instead:

$target_path = "../Filestore/";
$strFilePath = $target_path . basename( $_FILES['File1']['name']);
move_uploaded_file($_FILES['File1']['tmp_name'], $strFilePath);
$strFilePath = $target_path . basename( $_FILES['File2']['name']);
move_uploaded_file($_FILES['File2']['tmp_name'], $strFilePath);
$strFilePath= $target_path . basename( $_FILES['File3']['name']);
move_uploaded_file($_FILES['File3']['tmp_name'], $strFilePath);

This code uses a second variable for storing the target path with filename appended to the end. Also, I don't think you need to use basename when referencing the file name.

You can view the entire content of your $_FILES array by calling print_r( $_FILES ).

Regards,

Rob.

Many thanks Rob, you have saved me many more frustrating hours.

My complete script does the following;
Deletes any files from the target folder
Uploads new files
Zips the new files
Sends the zipped file as an attachment, with other form fields as an email.

Once completed I will post for other to review/use as they see fit.
Again many thanks

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.