Remove empty array elements from the $_FILES array
-
17-02-2021 - |
Pergunta
I have a photo album, with a 'photos' field in database which has serialized data and is base 64 encoded. I can upload up to 21 photos at the same time for the album (multiple uploading). When trying to add new photos to the album on edit mode, I can't get the new $_FILES array to merge with the old array in the database. I want to update only the values that I have changed. So let's say I already had 2 images inside my album, I would like to add a 3rd image without losing the other 2 images. I know I need to use unset() to delete empty values but I think i'm not doing it correctly. Here's my code:
if (isset($_REQUEST['action']) && $_REQUEST['action'] == 'edit') {
//select photo album and get photos and descriptions to be merged with new.
$album_id = $_REQUEST['album_id'];
$old_photos = null;
$old_descriptions = null;
$getAlbumQ = mysql_query("select * from albums where id='$album_id'");
while ($old_album = mysql_fetch_array($getAlbumQ)) {
$old_photos = unserialize(base64_decode($old_album['photos']));
$old_descriptions = unserialize(base64_decode($old_album['descriptions']));
}
if (isset($_POST['album_name']) && isset($_POST['desc'])) {
$name = $_POST['album_name'];
$desc = $_POST['desc'];
$idesc = array();
$target_path = "../uploads/albums/";
foreach ($_FILES as $k => $v) {
//first upload photos
$path = $target_path . basename($v['name']);
if(move_uploaded_file($v['tmp_name'], $path)) {
$hasUpload = true;
}
}
for ($j = 1; $j < 21; $j++) {
$img_index = $j;
$img_desc = $_POST['desc_' . $img_index];
$asdf = $_FILES['image_' . $img_index]['name'];
array_push($idesc, $img_desc);
}
foreach( $_FILES['images']['name'] as $key => $value ) {
if( empty($value) ) {
unset( $_FILES['images']['name'][$key] );
}
}
for ($i = 1; $i < 21; $i++) {
if($_FILES['image_'.$i]['name']!= '')
{
$hasUpload = true;
$presults = array_merge($old_photos, $_FILES); //THE PROBLEM WITH MERGING ARRAYS OCCURS HERE
$dresults = array_merge($old_descriptions, $idesc);
$images = base64_encode(serialize($presults));
$descriptions = base64_encode(serialize($dresults));
$posted = date("Y-m-d H:i:s");
}
else {
$hasUpload = false;
$presults = $old_photos;
$dresults = $idesc;
$images = base64_encode(serialize($presults));
$descriptions = base64_encode(serialize($dresults));
$posted = date("Y-m-d H:i:s");
}
}
}
}
Solução
I tried something similar to what Muu suggested. Combined it with another piece of code of a custom merge function found here http://keithdevens.com/weblog/archive/2003/Mar/30/MergeTwoArrays and it worked fine! Thanks for your help
Just needed to add the following lines of code outside the for ($i = 1; $i < 21; $i++) loop:
//delete empty values for $_FILES array
foreach ($_FILES as $key => $value) {
foreach ($value as $k => $v) {
if ($k=='name' && $v!='') {
break;
} else {
unset($_FILES[$key]);
}
}
}
//custom array merge function
function merge(&$a, &$b){
$keys = array_keys($a);
foreach($keys as $key){
if(isset($b[$key])){
if(is_array($a[$key]) and is_array($b[$key])){
merge($a[$key],$b[$key]);
}else{
$a[$key] = $b[$key];
}
}
}
$keys = array_keys($b);
foreach($keys as $key){
if(!isset($a[$key])){
$a[$key] = $b[$key];
}
}
}
then instead of array_merge(), I used merge() inside the for ($i = 1; $i < 21; $i++) loop:
$presults = merge($old_photos, $_FILES);
Outras dicas
Instead of removing the empty values from the array, why not just ignore them? For example:
$nonEmptyArray = array();
foreach ($_FILES as $k => $v) {
if (!$v) {
continue;
}
$nonEmptyArray[$k] = $v;
}
$_FILES = $nonEmptyArray;