Žan Anđić
asked on
Multiple upload files with PHP and MySQL, save data and showing them
Hi,
I have SQL table like this:
id | name | surname | dateofbirth | address | contact | dateofentrie | attachement1 | attachement2 | otherattachements
So I need in one form to add 2 files in 2 fields with input type="file", and one field is for upload multiple files.
Maybe is good to automatic rename files, for example, attachement1: name_surname_cv_dateofentr ie.pdf
or if is possible to automatically make new directory if not exist which is named from inputs in fields "name" and "surname".
So I have list of users, and every user is clickable, when click on name, opening user details. In user details I need to show all informations from columns in SQL table and I need to show: example: CV - name_surname_cv_dateofentr ie.pdf which is clickable and opening that file. And where is Other attachements I need to show list of files, all files need to be clickable.
I know how to make that for no multiple files, but didnt sure about rename, and moving and creating directories. I am searching for example like this on net, and tutorial, but no successfull.
I have file with functions named: functions.php
Thank you
I have SQL table like this:
id | name | surname | dateofbirth | address | contact | dateofentrie | attachement1 | attachement2 | otherattachements
So I need in one form to add 2 files in 2 fields with input type="file", and one field is for upload multiple files.
<?php
require ('functions.php');
if (isset($_POST['submit'])){
$name=$_POST['name'];
$surname=$_POST['surname'];
$dateofbirth=$_POST['dateofbirth'];
$address=$_POST['address'];
$contact=$_POST['contact'];
$dateofentrie=$_POST['dateofentrie'];
$attachement1=$_FILES['attachement1'];
$url = uploadAttachement1($attachement1);
$attachement2=$_FILES['attachement2'];
$url2 = uploadAttachement2($attachement2);
$adduser=addNewUser($name,$surname,$dateofbirth,$address,$contact,$dateofentrie,$attachement1,$attachement2,$otherattachements);
if ($addNewUser) {
header ('Location: users_list.php');
}
else {
echo "Error";
}
}
?>
<p><b>Name:</b>
<input type="text" class="form-control" name="name"></p>
<p><b>Surname:</b>
<input type="text" class="form-control" name="surname"></p>
<p><b>Date of birth:</b>
<input type="date" class="form-control" name="dateofbirth"></p>
<p><b>Address:</b>
<input type="text" class="form-control" name="address"></p>
<p><b>Contact:</b>
<input type="text" class="form-control" name="contact"></p>
<p><b>Date of entrie:</b>
<input type="text" class="form-control" name="dateofentrie" value="<?php echo date('d.m.Y'); ?>" readonly></p>
<p><b>Attachement1 (example: CV):</b>
<input type="file" class="form-control" name="attachement1"></p>
<p><b>Attachement2 (example: References):</b>
<input type="file" class="form-control" name="attachement2"></p>
<p><b>Other attachements:(example: certificates etc...)</b>
<input type="file" multiple class="form-control" name="otherattachements" ></p>
Maybe is good to automatic rename files, for example, attachement1: name_surname_cv_dateofentr
or if is possible to automatically make new directory if not exist which is named from inputs in fields "name" and "surname".
So I have list of users, and every user is clickable, when click on name, opening user details. In user details I need to show all informations from columns in SQL table and I need to show: example: CV - name_surname_cv_dateofentr
I know how to make that for no multiple files, but didnt sure about rename, and moving and creating directories. I am searching for example like this on net, and tutorial, but no successfull.
I have file with functions named: functions.php
function uploadAttachement1($attachement1) {
if($attachement1){
$upload=move_uploaded_file($attachement1['tmp_name'],'documents/'.$attachement1['name']);
if($upload) {
return "documents/".$attachement1['name'];
}
else {
return null;
}
}
}
function uploadAttachement2($attachement2) {
if($attachement2){
$upload=move_uploaded_file($attachement2['tmp_name'],'documents/'.$attachement2['name']);
if($upload) {
return "documents/".$attachement2['name'];
}
else {
return null;
}
}
}
Thank you
ASKER
Thank you for answer,
For make new directories I can maybe add column n DB identification number from personal card (jmbg) and when making directory use $name,$surname and $jmbg
I can make new table in DB, named files, and make columns. What is the best way? how to table where is files with user details?
How to do that with JSON?
For make new directories I can maybe add column n DB identification number from personal card (jmbg) and when making directory use $name,$surname and $jmbg
I can make new table in DB, named files, and make columns. What is the best way? how to table where is files with user details?
How to do that with JSON?
You can use a unique user id to create a directory if you wish.
To create a separate table for your files I would do this
For each attachment you would add a record to this table linked on userid
Path is the name of the file (with directory) on disk
Original filename is the name the user used when they uploaded the file.
You would then retrieve your data like so
The first record gives you your standard user data which you use to populate the profile as well as the first attachment. You then iterate over the remaining records to get the rest of the attachments.
To create a separate table for your files I would do this
create table `attachments`(
`id` int NOT NULL AUTO_INCREMENT ,
`date` timestamp DEFAULT CURRENT_TIMESTAMP ,
`usreid` int ,
`path` varchar(255) ,
`original_filename` varchar(255) ,
PRIMARY KEY (`id`)
)
(the timestamp is optional - I added it in case upload date is important)For each attachment you would add a record to this table linked on userid
Path is the name of the file (with directory) on disk
Original filename is the name the user used when they uploaded the file.
You would then retrieve your data like so
SELECT * FROM userTable u LEFT JOIN attachments a ON u.id = a.userid
The first record gives you your standard user data which you use to populate the profile as well as the first attachment. You then iterate over the remaining records to get the rest of the attachments.
// Assume $userid holds id of user you want to view
$query = "SELECT * FROM userTable u LEFT JOIN attachments a ON u.id = a.userid WHERE u.id = '{$userid}'";
$result = $mysqli->query($query);
if (!$result) {
// handle error here
}
// Get first record for user data and first attachment
$row = $result->fetch_object();
// Populate user data here and first attachment
while ($row = $result->fetch_object()) {
// complete rest of attachment list here
}
ASKER
Thank you
What is solution without creating table in database for files?
After uploading show array with filenames? How ?
What is solution without creating table in database for files?
After uploading show array with filenames? How ?
First of all change the name on your <input> to an array like this
<input type="file" multiple class="form-control" name="otherattachements[]" >
You could then use something like this to generate a string containing the data for the additional attachments$otherattachment = isset($_FILES['otherattachements']) ? $_FILES['otherattachements'] : array('name' => array());
$attachments_array= array();
foreach($otherattachment['name'] as $key => $attachment) {
$attachment = new stdClass;
$attachment->name = $attachment;
$savepath = getUserSavePath($userid);
// Save the file to the right location
move_uploaded_file($otherattachment['tmp_name'][$key], $savepath);
$attachment->path = $savepath;
$attachments_array[] = $attachment;
}
$dbattachments= json_encode($attachments_array);
// Add $dbattachments to your query and save in the database
function getUserSavePath($userid) {
// Implement your unique path creation here
}
ASKER
Does that can all be in one function named: uploadFiles
so
so
function uploadFiles ($otherattachment){
$otherattachment = isset($_FILES['otherattachements']) ? $_FILES['otherattachements'] : array('name' => array());
$attachments_array= array();
foreach($otherattachment['name'] as $key => $attachment) {
$attachment = new stdClass;
$attachment->name = $attachment;
$savepath = getUserSavePath($userid);
// Save the file to the right location
move_uploaded_file($otherattachment['tmp_name'][$key], $savepath);
$attachment->path = $savepath;
$attachments_array[] = $attachment;
}
$dbattachments= json_encode($attachments_array);
if ($dbattachements) {
return "mypath/".$dbattachements;
}
else {
return null;
}
}
You can put it wherever you want. The code is sample code only you need to adapt it to your situation.
ASKER
Tryed, upload just one file :(
You are going to have to give me more than that.
ASKER
I am attached to you my index.php file, and functions.php file where is function.
in index.php file on line 388 is input field and on lines 97 is final function for add entry in database, and on lines 93 and 92 are variables for documents upload (multiple).
In functions file
on the end you can see.
index.php
funkcije.php
in index.php file on line 388 is input field and on lines 97 is final function for add entry in database, and on lines 93 and 92 are variables for documents upload (multiple).
In functions file
on the end you can see.
index.php
funkcije.php
That function worked for me - uploaded 3 files and all were copied to the target folder.
Your code could be structured a bit better.
1. I would move the form processing into its own PHP file. This file loads the form with a require statement
2. Format your code so that it is neater - it is very difficult to debug code that is all over the place
3. This call
If you want help on this you are going to have to provide more information.
Do you get any errors.
What happens when you run the code - what do you expect what are your getting.
Your code could be structured a bit better.
1. I would move the form processing into its own PHP file. This file loads the form with a require statement
2. Format your code so that it is neater - it is very difficult to debug code that is all over the place
3. This call
$dodajunosbaza=dodajUnosBaza($ime,
Is very messy - consider using an object or an array to pass your variables rather than an overlong parameter list.If you want help on this you are going to have to provide more information.
Do you get any errors.
What happens when you run the code - what do you expect what are your getting.
ASKER
When I run code - uploaded success, and I get echo information: filename.txt is uploaded, filename2.txt is upladed... Now I want to get filenames and insert into variable which is: putanja_files=unosFajl ...
putanja_files is under dodajunosbaza=dodajUnosBaz a($ime,$pr ezime$.... ...$putanj a_files)
In above variables you can see putanja_rjesenje and putanja_anamneza, and when I click submit button, I in database write filename with full path, from return in function uploadRjesenje and uploadAnamneze. I want the same thing with uploadFajl and putanja_files.
putanja_files is under dodajunosbaza=dodajUnosBaz
In above variables you can see putanja_rjesenje and putanja_anamneza, and when I click submit button, I in database write filename with full path, from return in function uploadRjesenje and uploadAnamneze. I want the same thing with uploadFajl and putanja_files.
What I am hearing is you want to return the filenames from the function that saves them?
Create an array - store the paths in the array and return the array.
I am not 100% clear on what you are asking so I can't be specific on how to do this.
Create an array - store the paths in the array and return the array.
I am not 100% clear on what you are asking so I can't be specific on how to do this.
ASKER
Yes that is what I want,
how to create that array? how that needs to look like?
how to create that array? how that needs to look like?
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Yes, that works, thank youuu so much
I get text in my sql field:
Is there way to show that without brackets and quotes and commas, something like this:
dokumenti/ostali/fluid.txt
dokumenti/ostali/home_page .txt
dokumenti/ostali/kategorij akorisnika .txt
dokumenti/ostali/korisnik. png
To put <br> and make links to paths?
And one question more, is there way to use mkdir from variables $name, $surname, $number (number - unique number in database for every user from personal card). I am trying something before, but I have trouble with special characters, if name and surname have čšćžđ, file name be like example:
This is how need to be: Žan_Anđić_178000.doc
I get like this: %$'/an_An%/*-%i/%'_17800.d oc
Something with utf8 encode?
I get text in my sql field:
["dokumenti/ostali/fluid.txt","dokumenti/ostali/home_page.txt","dokumenti/ostali/kategorija korisnika.txt","dokumenti/ostali/korisnik.png"]
Is there way to show that without brackets and quotes and commas, something like this:
dokumenti/ostali/fluid.txt
dokumenti/ostali/home_page
dokumenti/ostali/kategorij
dokumenti/ostali/korisnik.
To put <br> and make links to paths?
And one question more, is there way to use mkdir from variables $name, $surname, $number (number - unique number in database for every user from personal card). I am trying something before, but I have trouble with special characters, if name and surname have čšćžđ, file name be like example:
This is how need to be: Žan_Anđić_178000.doc
I get like this: %$'/an_An%/*-%i/%'_17800.d
Something with utf8 encode?
You can but that defeats the purpose. You want to be able to access those documents - you are storing multiple document paths in a single list.
I used json_encode so that you can get the array back again when you need those paths
If you do it the other way you will have to still explode (or similar) the data to get the paths back.
JSON is the easiest way of doing this.
I used json_encode so that you can get the array back again when you need those paths
$paths = json_decode($row['extra_files_column_name_here']);
// Now paths is an array of paths.
If you do it the other way you will have to still explode (or similar) the data to get the paths back.
JSON is the easiest way of doing this.
ASKER
You want to be able to access those documents - you are storing multiple document paths in a single list.
Yes that is what I need. Exactly.
I will try to do that, now.
ASKER
// IF SUCCESSFUL THEN ADD TO RETURN ARRAY
$files[] = '<a href="'.$targetpath.'">'.$targetpath.'</a><br>';
}
}
}
// RETURN ARRAY OF PATHS TO SUCCESSFUL FILE UPLOADS
return implode(' ',$files);
}
I am try this, and get all what I want, but with quotes on begin and on the end.
"<a href=dokumenti/ostali/korisnik.png>dokumenti/ostali/korisnik.png</a><br> <a href=dokumenti/ostali/peel_stick2.png>dokumenti/ostali/peel_stick2.png</a><br>"
Need to remove (")
Let me explain why I would not do it this way.
When you store the actual format of the link in the database it locks you into that format. If you decide to change the format in the future - even by 1 character you have to change every record in your database - not good practice.
I also would stay with JSON over implode as it is a standard - it is the same amount of effort to use as explode / implode (if not less) and it is a widely supported and understood format.
As to the issue of the quotes - I don't know what quotes you are referring to nor where you get your data from - the implode should not be causing this - whatever it is - it is not in the code you have shown.
When you store the actual format of the link in the database it locks you into that format. If you decide to change the format in the future - even by 1 character you have to change every record in your database - not good practice.
I also would stay with JSON over implode as it is a standard - it is the same amount of effort to use as explode / implode (if not less) and it is a widely supported and understood format.
As to the issue of the quotes - I don't know what quotes you are referring to nor where you get your data from - the implode should not be causing this - whatever it is - it is not in the code you have shown.
"<a href=dokumenti/ostali/koriAre you referring to the double quotes around the above? If so - how are you outputting that string - I need to see all the code from the time you get it from the DB until you output it - what you have given me is simply not enough.snik.png>d okumenti/o stali/kori snik.png</ a><br> <a href=dokumenti/ostali/peel _stick2.pn g>dokument i/ostali/p eel_stick2 .png</a><b r>"
ASKER
Thank you
I fix, put
How to this files put in new directory if not exist, directory can be named just from $jmbg (id number), no need for name and surname?
I fix, put
$putanja_files=str_replace('"','',$red['prilog_ostali']);
Now showing good. This way is not useful if I need to change something in files, or upload more, or something, but when you adding new user in database, and upload files, once when uploaded no changes. How to this files put in new directory if not exist, directory can be named just from $jmbg (id number), no need for name and surname?
This way is not useful if I need to change something in files, or upload more, or somethingWhich is why I would use JSON
Add to files
1. Get record from database
2. Get field from record - $row['otherattachements ']
3. Decode
$files = json_decode($row['otheratt
4. Add new file
$files[] = "Path/To/New/File.txt";
5. Encode
$otherattachments = json_encode($files);
6. Put back in the database
UPDATE [TABLENAME] SET otherattachments='{$otherattachments}' WHERE [FILTER TO FIND RECORD]
How to this files put in new directory if not exist, directory can be named just from $jmbg (id number), no need for name and surname?I am not sure I understand - are you asking
1. How to make a directory
2. Find a name for a directory
3. How to save the files to a specified directory?
ASKER
I need to save file in directory which will be created for everyuser with mkdir from variable $jmbg and after save get path like on this what we success finished. Just need to save files in new directory
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Works perfectly.
Thank you Julian.
Now I have just little trouble with special characters when uploading file, making directory and new file name.
I need to replace ćčšđž characters with: ccsdz
I try with str_replace but not successful
EDIT
Successfull
I put this and now works all well
Thank you Julian.
Now I have just little trouble with special characters when uploading file, making directory and new file name.
I need to replace ćčšđž characters with: ccsdz
I try with str_replace but not successful
EDIT
Successfull
I put this and now works all well
$characters= array("ć", "č", "š", "ž", "đ", "Ć", "Č", "Š", "Ž", "Đ");
$replacechar= array("c", "c", "s", "z", "d", "C", "C", "S", "Z", "D");
$name=str_replace($characters,$replacechar,$name);
ASKER
Thank you Julian Hansen for your time and help :)
You are welcome.
And if you have two users with the same name and surname - again you have a collision.
What I would do is rename the file using an ID / GUID / random name or similar. Store this in the database. At the same time also store the original filename - the one that was used by user when they uploaded. I would also keep the files in a flat space.
If you need to download the file you get the id from the database and in the download code you create (using headers) the filename you want it to download as again using the original name you saved in the database.
This option allows you the most flexibility.
Now to the other files. This points to a potentially bad DB design. A better option might be to rationalise your DB and create a files table that you then populate with files linked to the parent user on the user id. This will require a JOIN to retrieve the data but it will mean you can handle as many files per user as required.
If you want / have to store in a single record then I would consider creating an array of objects that store the file details and then JSON encode (or serialize - I prefer JSON) and store the JSON string in the other attachments field.
When you display the user record you simply json_decode() the string and use the decoded data to render the file list.