Reputation: 366
I have a dynamic form,that looks pretty much like this:
The idea is to add a new row every time I click "Add row" ( usign JQuery here) and each new row should contain a "Browse" button, allowing to upload a file for each added user newly added. The remove button simply removes unneeded rows.
I'm using PHP and MySQL to store the input fields data and file path.
My problem is that I cannot figure out how to implement the "upload file" correctly and also how to add the path/filename to the php/mysql query.
My code, so far, looks like:
<?php
$mysql_db_hostname = "localhost";
$mysql_db_user = "root";
$mysql_db_password = "password";
$mysql_db_database = "dynamic";
$dbc = mysql_connect($mysql_db_hostname, $mysql_db_user,
$mysql_db_password) or die("Could not connect database");
mysql_select_db($mysql_db_database, $dbc) or die("Could not select database");
?>
<?
if (isset($_POST['add_account'])) {
if ($_POST['fields']) {
foreach( $_POST['fields'] as $key=>$fieldArray ) {
// new code added from here
if (!empty($_FILES)) {
$uploaddir = 'upload/';
$uploadfile = $uploaddir . basename($_FILES['userfiles']['name']);
if (move_uploaded_file($_FILES['userfiles']['tmp_name'], $uploadfile)) {
echo "File is valid, and was successfully uploaded.<br />";
} else {
echo "File not uploaded!<br />";
}
}
// new code added until here
$keys = array_keys($fieldArray);
$values = array_map("mysql_real_escape_string",$fieldArray);
$q = "INSERT INTO accounts (".implode(',',$keys).", file_uploaded) VALUES ('".implode('\',\'',$values)."', ".$uploadfile." )";
$r = mysql_query($q, $dbc );
}
}
echo "<i><h2><strong>" . count($_POST['fields']) . "</strong> Account(s) Added</h2></i>";
}
?>
<?php if (!isset($_POST['add_account'])) { ?>
<form method="post" action="" enctype="multipart/form-data">
<p id="add_field"><a class="btn btn-default" href="#">Add Rows</a></p>
<table id="myTable">
<thead>
<tr>
<th>#</th>
<th>First Name:</th>
<th>Last Name:</th>
<th>E-mail:</th>
<th>Upload file</th>
<th></th>
</tr>
</thead>
<tbody id="container">
</tbody>
</table>
<input class="btn btn-default" type="submit" name="add_account" value="Submit" />
</form>
<?php } ?>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script type="text/javascript">
$(function(){
var counter = 0;
$('p#add_field').click(function(){
counter += 1;
$('#container').append(
'<tr><td>' + counter + '</td><td><input name="fields['+counter+'][first]" type="text" placeholder="First Name" required/></td><td><input name="fields['+counter+'][last]" type="text" placeholder="Last Name" required/></td><td><input name="fields['+counter+'][email]" type="email" placeholder="email" required/></td><td><input id="userfile" name="fields['+counter+'][file_uploaded][]" type="file" /></td><td><input button" value="Remove" onclick="delRow(this)"></td></tr>');
});
});
function delRow(currElement) {
var parentRowIndex = currElement.parentNode.parentNode.rowIndex;
document.getElementById("myTable").deleteRow(parentRowIndex);
}
</script>
If I try to echo $uploadfile
I get no result...
The result of the print_r($_FILES)
is:
Array
(
[fields] => Array
(
[name] => Array
(
[1] => Array
(
[file_uploaded] => Array
(
[0] => a4.jpg
)
)
)
[type] => Array
(
[1] => Array
(
[file_uploaded] => Array
(
[0] => image/jpeg
)
)
)
[tmp_name] => Array
(
[1] => Array
(
[file_uploaded] => Array
(
[0] => /tmp/phpIaNYYD
)
)
)
[error] => Array
(
[1] => Array
(
[file_uploaded] => Array
(
[0] => 0
)
)
)
[size] => Array
(
[1] => Array
(
[file_uploaded] => Array
(
[0] => 6063
)
)
)
)
)
The mysql table (accounts) looks like:
id | first | last | email | file_uploaded
The id field is set as Primary with Autoincrement , the rest are Varchar (300 ).
I can't figure out how to upload files and save the path in mysql using this kind of dynamic form.
Everything else works perfectly.
Can someone, please, give me some code example and put me on the right path with the upload files issue for this specific case?
Disclaimer: I know I should use PDO and mysqli. I'm learning PDO right now, but I'm yet far from knowing it, that's why I used old/classic mysql here. Also, most of the code is put together from various answers on similar issues found on this site.
Upvotes: 2
Views: 3243
Reputation: 366
@Aioros - With your help I have a fully functional code:
<?php
$mysql_db_hostname = "localhost";
$mysql_db_user = "root";
$mysql_db_password = "password";
$mysql_db_database = "dynamic";
$dbc = mysql_connect($mysql_db_hostname, $mysql_db_user,
$mysql_db_password) or die("Could not connect database");
mysql_select_db($mysql_db_database, $dbc) or die("Could not select database");
?>
<?
if (isset($_POST['add_account'])) {
if ($_POST['fields']) {
foreach( $_POST['fields'] as $key=>$fieldArray ) {
if (!empty($_FILES)) {
$uploaddir = 'upload/'; // Upload directory
if (!is_dir($uploaddir)) // Check if upload directory exist
{
mkdir($uploaddir); // If no upload directory exist, create it
}
$newname = time(); // Returns the current time measured in the number of seconds since the Unix Epoch (January 1 1970 00:00:00 GMT), to use it as part of the name
$random = rand(100,999); // Getting some random numbers to add in the file names, to avoid files with the same name
$name = $newname.'-'.$random.'-'.$_FILES['fields']['name'][$key]['file_uploaded'][0]; // File Name Construction
$tempFile = $_FILES['fields']['tmp_name'][$key]['file_uploaded'][0]; // Getting temporary file location and temporary name ( e.g. /tmp/random_string__here )
$uploadfile = $uploaddir . $name; // Concatenating upload dir name with the file name
if (move_uploaded_file($tempFile, $uploadfile)) { // If file moved from temp to upload location with the name we constructed above
echo 'File uploaded to '.$uploadfile.'.<br />';
} else {
echo 'File not uploaded!<br />';
}
}
$keys = array_keys($fieldArray);
$values = array_map("mysql_real_escape_string",$fieldArray);
$q = "INSERT INTO accounts (".implode(',',$keys).", file_uploaded) VALUES ('".implode('\',\'',$values)."', ".$uploadfile." )";
$r = mysql_query($q, $dbc );
}
}
echo "<i><h2><strong>" . count($_POST['fields']) . "</strong> Account(s) Added</h2></i>";
}
?>
<?php if (!isset($_POST['add_account'])) { ?>
<form method="post" action="" enctype="multipart/form-data">
<p id="add_field"><a class="btn btn-default" href="#">Add Rows</a></p>
<table id="myTable">
<thead>
<tr>
<th>#</th>
<th>First Name:</th>
<th>Last Name:</th>
<th>E-mail:</th>
<th>Upload file</th>
<th></th>
</tr>
</thead>
<tbody id="container">
</tbody>
</table>
<input class="btn btn-default" type="submit" name="add_account" value="Submit" />
</form>
<?php } ?>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script type="text/javascript">
$(function(){
var counter = 0;
$('p#add_field').click(function(){
counter += 1;
$('#container').append(
'<tr><td>' + counter + '</td><td><input name="fields['+counter+'][first]" type="text" placeholder="First Name" required/></td><td><input name="fields['+counter+'][last]" type="text" placeholder="Last Name" required/></td><td><input name="fields['+counter+'][email]" type="email" placeholder="email" required/></td><td><input id="userfile" name="fields['+counter+'][file_uploaded][]" type="file" /></td><td><input type="button" value="Remove" onclick="delRow(this)"></td></tr>');
});
});
function delRow(currElement) {
var parentRowIndex = currElement.parentNode.parentNode.rowIndex;
document.getElementById("myTable").deleteRow(parentRowIndex);
}
</script>
Upvotes: 0
Reputation: 4383
You are almost there. Your problem now is simply that you are using
$_FILES['userfiles']['name']
but your file inputs are not called userfiles
at all. Looking at your $_FILES
dump, you should do something like:
$_FILES['fields']['name'][$key]['file_uploaded']
If I'm reading your form and code correctly, that is. It'a bit of a weird array structure, because of the kind-of-weird input names that you chose in the form, but it should work.
Upvotes: 1