I am trying to validate this form dynamically using PHP so each file gets the same validation instead of only one file being validated. Below is my code to try and explain this better.
This is the for loop which outputs a number of <input type="file" /> fields to the user.
$items = sanitize($_GET['item']);
for($i=1; $i<=$items; $i++) {
echo $item = '<input type="file" name="photo'. $i .'" />';
}
This is the validation for one of these fields
$file_size = $_FILES['photo1']['size'];
if($file_size > 10485760) {
echo 'Photo 1 is too large. Maximium file size is 10MB.';
}
I am not sure how to accomplish this validation for every field in the for loop. This is what I have tried so far.
if($file_size.$i > 10485760) {
echo 'Photo '. $i .' is too large. Please choose a smaller file.';
}
This does not work though. Please can someone help me out with this?
Many thanks in advance, Harry
Array keys can be dynamic:
for ($i = 1; $i <= $some_limit; $i++) {
$size = $_FILES["photo{$i}"]['size'];
if ($size > ...) { etc... }
}
With your $size . $i, you'd be taking the size of the first file, e.g. 1024 bytes, and concatenating it with the $i value, e.g. 1024 . 2 and ending up with 10242.
Try something like:
foreach ($_FILES as $id => $details) {
$size = $details['size'];
# validate...
}
input name can be with square bracket. When form is submitted input fields can be accessed as array. such as:
html form:
<input type="file" name="photo[]">
<input type="file" name="photo[]">
<input type="file" name="photo[]">
php:
foreach($_FILES['photo'] as $key => $p) {
$file_size = $p['size'];
if($file_size > 10485760) {
echo "Photo $key is too large. Maximium file size is 10MB.";
}
}
This should work. Thank You.
Related
I have the following code Multiple text and type File Using an array to upload file and Text.
in this code, if I remove type file this code is working. but after use file is not work
Here is the Form
<form method="post" enctype="multipart/form-data">
<?php
$data_array = array('text','text2','file','file2');
foreach($data_array as $data_name){ ?>
<input type="hidden" name="data_name[]" value="<?php echo $data_name; ?>">
<?php if(strpos($data_name,'text') !== false){ ?>
<input name="data_value[]" type="text" />
<?php }
if(strpos($data_name,'file') !== false){ ?>
<input name="data_value[]" type="file" /> <?php }
} ?>
<input type="submit" name="submit" value="Add" />
</form>
Here is The Php Code, I Think More Improvement on $_FILE Part
if(isset($_POST['submit'])){
if(isset($_FILES['data_name'])){
foreach(array_combine($_FILES['data_name'],$_POST['data_value']) as $dataname => $datavalue){
$file_name = $_FILES['data_name']['name'];
echo file_name;
}
}
if(isset($_POST['data_name'])){
foreach(array_combine($_POST['data_name'],$_POST['data_value']) as $dataname => $datavalue){
echo $dataname.' - '.$datavalue;
}
}
}
Here is The Error of File..
Warning: array_combine(): Both parameters should have an equal number
of elements in pagename.php on line 25
Warning: Invalid argument supplied for foreach() in pagename.php on line 25
I Need Output Like This -
text = value
text2 = value2
file = file.jpg
file2 = file2.jpg
As stated explicitly in the error message, $_FILES['data_name'] and $_POST['data_value' are not the same size. (And I'm pretty sure the foreach is failing because the array_combine failed).
That is explained by you here: "if I remove type file this code is working. but after use file is not work".
If you want to use array_combine(), the arrays must be of the same size.
If you add a filter (eg if(strpos($data_name,'file') !== false)) the potential exists that the arrays will not match (as this problem indicates).
One approach would be to filter out the "data_name[]" inputs with the same condition as the "data_value[]" inputs.
Or the other way round: add an else on the above mentioned if that produces <input name="data_value[]" type="hidden" /> (notice the type). This will ensure the arrays are the same size. You will have to figure out what to do with these "dummy" inputs in the php code. Perhaps give them a value (like value="dummy") that you can test on.
replace your php-code with this:
function get_names_for_entity($name, $arr)
{
if (!empty($arr)) {
$ret = array_values(
array_filter(
$arr,
function ($itm) use ($name) {
return strpos($itm, $name) !== false;
}
)
);
} else {
$ret = [];
}
return $ret;
}
$names_a = [
'file' => get_names_for_entity('file', $_POST['data_name']),
'text' => get_names_for_entity('text', $_POST['data_name'])
];
if (isset($_POST['submit'])) {
if (isset($_POST['data_value'])) {
foreach ($_POST['data_value'] as $dataname_idx => $datavalue) {
echo $names_a['text'][$dataname_idx].' - '.$datavalue;
}
}
if (isset($_FILES['data_value'])) {
foreach ($_FILES['data_value']['name'] as $dataname_idx => $datavalue) {
$file_name = $_FILES['data_value']['name'][$dataname_idx];
echo $names_a['file'][$dataname_idx].' - '.$file_name;
}
}
}
I've got the following input fields:
<input name="file1" type="file">
<input name="file2" type="file">
<input name="files[]" type="file" multiple>
I'm trying to figure out the best way to check which of the fields above are not empty and perform some DB action with the ones that have files in them.
I can check them each one manually like this but I am wondering if there is a better way to do this:
if(!empty($_FILES['file1']['name']) {
// Perform checks/etc for file1
}
if(!empty($_FILES['file2']['name']) {
// Perform checks/etc for file2
}
if(!empty($_FILES['files']['name'][0]) {
// Loop the array, perform checks/etc for each one
}
This will loop through all the files and tell you which ones are empty, and put the files that have content in the $submittedFiles array.
$submittedFiles = [];
foreach ($_FILES as $n => $f) {
if (!empty($f['name']) && !empty($f['name'][0])) {
$submittedFiles[] = $f;
} else {
echo $n.' is empty';
}
}
var_dump($submittedFiles);
protected function upload($name) {
$files = array();
// if block 1
if(!empty($_FILES[$name]['tmp_name'])) {
for($i = 0; $i < count($_FILES[$name]['tmp_name']); $i++) {
// if block #2
if(!empty($_FILES[$name]['tmp_name']) && is_uploaded_file($_FILES[$name]['tmp_name'][$i])) {
# we're dealing with multiple uploads
$handle['key'] = $name;
$handle['name'] = $_FILES[$name]['name'][$i];
$handle['size'] = $_FILES[$name]['size'][$i];
$handle['type'] = $_FILES[$name]['type'][$i];
$handle['tmp_name'] = $_FILES[$name]['tmp_name'][$i];
// put each array into the $files array
array_push($files,$this->_process_image($handle));
}
#block 3...
}
return $files;
}
return false;
}
I'm trying to create a function that will handle multiple upload scenarios: multiple file uploads per submit, and one file upload per submit, using a variety of file inputs.
The above method...
works as expected with two inputs
<input name="multiple[]" type="file">
<input name="multiple[]" type="file">
and a single input using multiple...
<input name="multiple[]" type="file" multiple>
but not a single input using a single upload
<input name="single" type="file">
Now, I noticed that if I change the name of single to single[] it works. So I copied block #2 and added it as another block (where #3 is), but this time without using [$i] and it worked for the single input, but failed if i had multiple inputs but only used one input to upload one file (not uploading 2 files using both inputs).
My brain hurts. How can I get this to work for all these scenarios?
Edit: When I say it's not working, I mean it's not even processing. No output, no errors, nothing. I think it's just being skipped over, which is why I added block #3...
HTML
<form action="file-upload.php" method="post" enctype="multipart/form-data">
Send these files:
<br />
<input name="userfile[]" type="file" />
<br />
<input name="userfile[]" type="file" />
<br />
<input type="submit" value="Send files" />
PHP(file-upload.php)
<?php
if ($_FILES['upload']) {
$file_ary = reArrayFiles($_FILES['userfile']);
foreach ($file_ary as $file) {
if(intval($file['error'])==4){
continue;
}
//If you upload a single file this will execute only once
print 'File Name: ' . $file['name'];
print 'File Type: ' . $file['type'];
print 'File Size: ' . $file['size'];
}
}
function reArrayFiles($file_post) {
$file_ary = array();
$file_count = count($file_post['name']);
$file_keys = array_keys($file_post);
for ($i=0; $i<$file_count; $i++) {
foreach ($file_keys as $key) {
$file_ary[$i][$key] = $file_post[$key][$i];
}
}
return $file_ary;
}
?>
Files Output :
Figured it out and it was really easy. I needed to check if the $_FILES array contained more than one file and process accordingly. probably a little bit more code than I'd like, but it's working exactly how I wanted.
protected function upload($name) {
$files = array();
if(!empty($_FILES[$name]['tmp_name'])) {
# *** THIS IF BLOCK SOLVED THE PROBLEM ***
# JUST CHECK IF $_FILES HAS MORE THAN ONE FILE
if(count($_FILES[$name]['tmp_name']) > 1) {
for($i = 0; $i < count($_FILES[$name]['tmp_name']); $i++) {
if(!empty($_FILES[$name]['tmp_name']) && is_uploaded_file($_FILES[$name]['tmp_name'][$i])) {
# we're dealing with multiple uploads
$handle['key'] = $name;
$handle['name'] = $_FILES[$name]['name'][$i];
$handle['size'] = $_FILES[$name]['size'][$i];
$handle['type'] = $_FILES[$name]['type'][$i];
$handle['tmp_name'] = $_FILES[$name]['tmp_name'][$i];
array_push($files,$this->_process_image($handle));
}
}
return $files;
} else {
if(!empty($_FILES[$name]['tmp_name']) && is_uploaded_file($_FILES[$name]['tmp_name'])) {
# we're handling a single upload
$handle['key'] = $name;
$handle['name'] = $_FILES[$name]['name'];
$handle['size'] = $_FILES[$name]['size'];
$handle['type'] = $_FILES[$name]['type'];
$handle['tmp_name'] = $_FILES[$name]['tmp_name'];
return $this->_process_image($handle);
}
}
}
return false;
}
I've got this code, anyone help on making it work...
while($fetch = mysql_fetch_assoc($query)){
$image_name = $fetch['image_name'];
$image_location = $fetch['image_location'];
<img src="'.$image_location.'"/>
<input name="image['.$image_id.'][6x7]" type="checkbox" value="'.$image_name.'" /> 6x4
<br />
<input name="image['.$image_id.'][8x9]" type="checkbox" value="'.$image_name.'" /> 7x5
}
Display on different page...
foreach($_POST['image'] as $image_id => $name) {
$uploaded[] = $name;
echo''.$name.'<br />';
foreach($name as $size => $size) {
$uploaded[] = $size;
echo''.$size.'<br />';
}
}
Input Script
mysql_query("INSERT INTO table VALUES('', '$name', 'size')");
I am uploading both image name and size (from the checkboxes 6x4, 7x5)
I am able to input the size into the database but image name just says Array.
I know this is an obvious fix but I just can't get my head around the multiple arrays is the checkbox values!
Any help of feedback is welcome! HELP!
I assume your $image_location and $image_name are fine so you have correct values on your checkboxes? Otherwise we would need some more details..
Try below to display that correctly then (you're using multidimensional array):
foreach($_POST['image'] as $image_id => $image) {
foreach($image as $size => $name) {
$uploaded[] = $name;
echo''.$name.'<br />';
$uploaded[] = $size;
echo''.$size.'<br />';
}
}
<input name="image['.$image_id.'][]" type="checkbox" value="6x7" /> 6x4
<br />
<input name="image['.$image_id.'][]" type="checkbox" value="8x9" /> 7x5
The value should not be the image name, but the size you specified. You already have the image ID, so why include the filename? You can just extract that from your database again...
Also:
foreach($name as $size => $size) {
... is a bit weird: Using the $size var for key and value? That's asking for trouble. ;)
HTML:
Owner: input type="text" name="owner[]" />
Category:
<select name="cat[]">
<option value="clothes">Clothes</option>
<option value="shoes">Shoes</option>
<option value="accessories">Accessories</option>
</select>
Upload: <input type="file" name="image[]" />
whith function that clone the same fields when click on "+ button"
I count the POST field with:
$num = count($_FILES['image']['name']);
because i want to know how many times the end user clone the fields.
what i want is Make sure that the user has to fill all fields which he opend with "+ button" i cant check all the hidden fields i want to check just the field he opend.
so what can i do ?
i cant do like this:
$owner = $_POST['owner'][$i];
$cat = $_POST['cat'][$i];
$file = $_FILES['image'][$i];
if ($owner && $cat && $file)
echo "bla bla bla";
else
echo "fill all the fields!";
can anyone help me ?
thank you
There are some points which you need to make sure beforehand. Whenever you are using any input field's name attribute as "owner[]" or "cat[]" or "image[]", you will get an array then. But since, input file's property accessing capability is already 2D array by default, so now you will be able to access those properties as a 3D array.
When you have added a "[]" for the input file field's name attribute, you will now get the name of the 1st file as "$_FILES['image'][0]['name']", because array indices start with 0. As per your question, you can validate using the following way:-
<?php
$numOwners = count($_POST['owner']);
$numCats = count($_POST['cat']);
$numFiles = count($_FILES['image']);
// Check to see if the number of Fields for each (Owners, Categories & Files) are the same
if ($numFiles === $numCats && $numFiles === $numOwners) {
$boolInconsistencyOwners = FALSE;
$boolInconsistencyCats = FALSE;
$boolInconsistencyFiles = FALSE;
for ($i = 0; $i < $numFiles; $i++) {
if (empty($_POST['owner'][$i])) {
$boolInconsistencyOwners = TRUE;
break;
}
if (empty($_POST['cat'][$i])) {
$boolInconsistencyCats = TRUE;
break;
}
if (!is_uploaded_file($_FILES['image'][$i]['tmp_name'])) {
$boolInconsistencyFiles = TRUE;
break;
}
}
if ($boolInconsistencyOwners || $boolInconsistencyCats || $boolInconsistencyFiles) {
echo "I knew that there will be some problems with users' mentality!";
// Redirect with proper Error Messages
}
else {
echo "Wow, Users have improved & have become quite obedient!";
// Proceed with normal requirements
}
}
else {
echo "Something fishy is going on!";
}
?>
Hope it helps.