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");
}
}
}
}
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);
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;
Related
I have this php code that's supposed to check how many times a single item is in an array and put the amount in the value of that key.
im asking, why does the $duplicates[$item] += 1; create a new array instead of appending it to the existing array
here is the picture of the output I get.
this is my code:
$itemQuery = $con->prepare("SELECT cart_value FROM active_carts WHERE username=:prodName");
$itemQuery->bindParam(":prodName" , $uname , PDO::PARAM_STR);
$itemQuery->execute();
$itemCount = $itemQuery->fetchAll();
$arrax = $itemCount[0]["cart_value"];
$itemArrX = explode(",", $arrax);
$inQuestion = array();
$duplicates = array();
foreach ($itemArrX as $item) {
if (in_array($item , $inQuestion)) {
$counter = 0;
if (!array_key_exists($item , $duplicates)) {
$duplicates[$item] = $counter;
// doesnt even execute
} else {
echo $duplicates[$item]; // echoes a new array every time
$duplicates[$item] += 1;
}
} else {
array_push($inQuestion, $item);
}
}
It is rather simple, you never created that item in the array.
$data[$key] = $value; //examine that.
try this $duplicates[$item] = $item;
then $duplicates[$item] += 1;
If you're just looking for a count of duplicate values, I like the suggestion about array_count_values() in the comments. That can be run through array_filter() to remove the non-duplicate values.
$itemQuery = $con->prepare("SELECT cart_value FROM active_carts WHERE username=:prodName");
$itemQuery->execute([":prodName"=>$uname]);
$itemArrX = explode(",", $itemQuery->fetchColumn(0));
$itemArrX = ["foo","bar","baz","bar","boo","baz"];
$duplicates = array_filter(array_count_values($itemArrX), function($v){return $v>1;});
$inQuestion = array_unique($itemArrX);
print_r($duplicates);
print_r($inQuestion);
Or here's a condensed version of your code which should work just fine.
$itemQuery = $con->prepare("SELECT cart_value FROM active_carts WHERE username=:prodName");
$itemQuery->execute([":prodName"=>$uname]);
$itemArrX = explode(",", $itemQuery->fetchColumn(0));
$itemArrX = ["foo","bar","baz","bar","boo","baz"];
$duplicates = [];
$inQuestion = [];
foreach ($itemArrX as $item) {
if (in_array($item, $inQuestion)) {
echo $duplicates[$item];
$duplicates[$item]++;
} else {
$duplicates[$item] = 1;
$inQuestion[] = $item;
}
}
print_r($duplicates);
print_r($inQuestion);
How can I access the contents of $value[$i] which is an array. No luck using foreach in the form below.
The idea is to loop through $contentArray and display one item from each sub-array on every iteration.
$addsContent = $Adds->selectAdds(10);
$sharedArticlesContent = $SharedContent->getSharedContent($topic_selected, $filter_selected);
$blogPostsContent = $BlogPosts->getRecentBlogPostsByTopic("business");
$contentArray = array(
$sharedArticlesContent,
$addsContent ,
$blogPostsContent
);
foreach($contentArray as $value)
{
if(count($value)>$maxLength)
{
$maxLength = count($value);
}
}
for($i=0; $i<$maxLength; $i++)
{
foreach($contentArray as $value)
{
if(isset($value[$i]))
{
if($value==$sharedArticlesContent){
$data = $value[$i];
foreach($sharedArticlesContent as $data){
$post_id = $data['id'];
$uploaded_by = $data['uploaded_by'];
$text = $data['text'];
$image = $data['image'];
require 'template1.php';
}
}elseif($value==$addsContent){
//template2
}else{
//template3
}
}
}
}
You're dealing with an associative array here, you can access it like that:
<?php
$addsContent = $Adds->selectAdds(10);
$sharedArticlesContent = $SharedContent->getSharedContent($topic_selected, $filter_selected);
$blogPostsContent = $BlogPosts->getRecentBlogPostsByTopic("business");
$contentArray = array(
$sharedArticlesContent,
$addsContent ,
$blogPostsContent
);
foreach($contentArray as $value)
{
if(count($value)>$maxLength)
{
$maxLength = count($value);
}
}
for($i=0; $i<$maxLength; $i++)
{
foreach($contentArray as $value)
{
if(isset($value[$i]))
{
if($value==$sharedArticlesContent)
{
$post_id = $value[$i]['id'];
$uploaded_by = $value[$i]['uploaded_by'];
$text = $value[$i]['text'];
$image = $value[$i]['image'];
require 'template1.php';
}
elseif($value==$addsContent)
{
//template2
}
else
{
//template3
}
}
}
}
You don't need the foreach. $data is an associative array, you don't need to loop through it.
if($value==$sharedArticlesContent){
$data = $value[$i];
$post_id = $data['id'];
$uploaded_by = $data['uploaded_by'];
$text = $data['text'];
$image = $data['image'];
require 'template1.php';
}
I can't figure out a way to do this and I really bad with working with arrays so I hope someone can help me.
I have array $stuck that just contains names, like this
$stuck = array('Daniel','Alex','alfredo','dina');
I am using sort to put the names in alphabetical order, like this
sort($stuck);
Now the thing is I want to put this array into a csv or excel file so the first letter of name will be the title and all the names with this letter will be under this title.
This is an example of what I am trying to accomplish
Here try this. I added comments between the code.
$csvArray = array();
$nameArray = array('Daniel','Alex','alfredo','dina');
//Create an array that can be used for creating the CSV
foreach($nameArray as $name)
{
$firstLetter = strtoupper(substr($name, 0,1));
$csvArray[$firstLetter][] = $name;
}
//Determine the subarray which have the must rules
$maxRuleCount = 0;
foreach($csvArray as $firstLetter => $nameArray)
{
if(count($nameArray) > $maxRuleCount)
{
$maxRuleCount = count($nameArray);
}
}
//Create the first rule (letters)
$csvContent = implode(';', array_keys($csvArray));
$csvContent .= "\r\n";
//Loop through the CSV array and create rules of the names
for($i = 0 ; $i < $maxRuleCount ; $i++)
{
foreach($csvArray as $firstLetter => $nameArray)
{
$csvContent .= #$csvArray[$firstLetter][$i].';';
}
$csvContent .= "\r\n";
}
//The hole csv content is in the $csvContent variable now
//If you want to print it you need to add the text/plain header because of the \r\n new line characters
header("Content-Type:text/plain");
echo $csvContent;
Ouput is:
D;A
Daniel;Alex;
dina;alfredo;
<?php
$stuck = array('Daniel','Alex','Dina','durban','eigor','alfredo','dina');
// associate names with first letters in a new array
foreach ($stuck as $name) {
$first_letter = strtoupper( substr( $name, 0, 1 ) );
$new_name_array[ $first_letter ][] = $name;
}
// store the first letter list in an array and sort it
$first_letters = array_keys( $new_name_array );
sort( $first_letters );
// sort the name lists
foreach( array_keys( $new_name_array ) as $letter ) {
sort( $new_name_array[$letter] );
}
// output csv header row
echo "'".implode( "','", $first_letters )."'\n";
// output the CSV name rows
$i = 0;
while ( true ) {
$row = array();
$is_row = false;
foreach( $first_letters as $letter ) {
$row[] = $new_name_array[ $letter ][ $i ];
if( ! empty( $new_name_array[ $letter ][ $i ] ) ) $is_row = true;
}
if( ! $is_row ) exit;
echo "'" . implode( "','", $row ) . "'\n";
$i++;
}
?>
Outputs quoted CSV:
'A','D','E'
'Alex','Daniel','eigor'
'alfredo','Dina',''
'','dina',''
'','durban',''
<?php
$stuck = array('Daniel','Alex','alfredo','dina', 'eigor', 'durban');
sort($stuck);
$sortedNames = array();
$maxEl = 0;
foreach ($stuck as $name) {
$name = strtolower($name);
$sortedNames[$name{0}][] = $name;
$maxEl = count($sortedNames[$name{0}]) < $maxEl ? $maxEl : count($sortedNames[$name{0}]);
}
$headers = array_keys($sortedNames);
$finalArray = array($headers);
for($i = 0; $i < $maxEl; $i++) {
$tmpRow = array();
foreach ($sortedNames as $names) {
$tmpRow[] = isset($names[$i]) ? $names[$i] : '';
}
$finalArray[] = $tmpRow;
}
$file = fopen("names.csv","w");
foreach ($finalArray as $line)
{
fputcsv($file,$line);
}
fclose($file);
Here is my attempt at this question:
$names = array('Daniel','Alex','alfredo','dina', 'eigor', 'falfoul', 'fiona');
natcasesort($names);
$columns = array();
foreach ($names as $name) {
$first = strtoupper(substr($name, 0, 1));
$columns[$first][] = $name;
}
// pad the columns so they all have the same number of rows
$maxRows = 0;
foreach ($columns as &$col) {
$numRows = count($col);
if ( $numRows > $maxRows) {
$maxRows = $numRows;
}
}
// pad the columns
foreach ($columns as &$column) {
$column = array_pad($column, $maxRows, '');
}
$firstLetter = array_keys($columns);
$numCols = count($firstLetter);
// transpose the columns array
$rows = array();
foreach ($columns as $csvCol) {
foreach ($csvCol as $k=>$n) {
$rows[$k][] = $n;
}
}
// pad the rows to ensure they all have the same number of
// columns
foreach ($rows as &$row) {
$row = array_pad($row, $numCols, '');
}
// add the title row to the rows
array_unshift($rows, $firstLetter);
$handle = fopen("names.csv", 'w');
foreach ($rows as $fRow) {
fputcsv($handle, $fRow);
}
I'm using PHP/MySQL to upload multiple images for photo album. The information associated with the images (filenames, extensions, descriptions etc.) is stored in database as base64 encoded data. I'm also able to edit the album images. My problem now is that I also want to create thumbnails for each of the images when uploading them on insert and edit mode and also store the information for the thumbnails the same way I do for the images (base64 encoded). What's the best way to do that? Thanks
Here's my code:
<?php
//Code for the editing albums in database
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']));
$old_timestamp=$old_album['timestamp'];
}
if (isset($_POST['album_name']) && isset($_POST['desc'])) {
$name = mysql_real_escape_string($_POST['album_name']);
$desc = mysql_real_escape_string($_POST['desc']);
$idesc = array();
$target_path = "/uploads/albums/";
foreach ($_FILES as $key => $value) {
foreach ($value as $k => $v) {
if ($k === 'name' && $v !== '') {
break;
} else {
unset($_FILES[$key]);
}
}
//first upload photos
$path = $target_path . basename($old_timestamp.$value['name']);
if(move_uploaded_file($value['tmp_name'], $path)) {
$hasUpload = true;
}
}
for ($j = 1; $j < 21; $j++) {
$img_index = $j;
$img_desc = $_POST['desc_' . $img_index];
array_push($idesc, $img_desc);
}
foreach ($_FILES as $key => $value) {
foreach ($value as $k => $v) {
if ($k=='name' && $v!='') {
break;
} else {
unset($_FILES[$key]);
}
}
}
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];
}
}
}
for ($i = 1; $i < 21; $i++) {
$file_index = $i;
$file_number = $_POST['image_' . $file_index];
if($_FILES['image_'.$i]['name']!= ''){
$hasUpload = true;
$presults = merge($old_photos, $_FILES);
$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");
}
}
}
if (mysql_query("update albums set description = '$desc', name = '$name', photos='$images', descriptions='$descriptions' where id='$album_id'")) {
$hasAlbums = true;
} else {
$hasErrors = true;
}
} else {
//Code for the inserting albums in database
if (isset($_POST['album_name'])) {
if (isset($_POST['album_name']) && isset($_POST['desc'])) {
$name = mysql_real_escape_string($_POST['album_name']);
$desc = mysql_real_escape_string($_POST['desc']);
$idesc = array();
$timestamp = time();
$target_path = "/uploads/albums/";
foreach ($_FILES as $k => $v) {
//first upload photos
$path = $target_path . basename($timestamp.$v['name']);
if(move_uploaded_file($v['tmp_name'], $path)) {
$img_index = explode('_', $k);
$img_index = $img_index[1];
$img_desc = $_POST['desc_' . $img_index];
array_push($idesc, $img_desc);
$file_name = $timestamp.$v['name'];
$hasUpload = true;
}
}
$images = base64_encode(serialize($_FILES));
$descriptions = base64_encode(serialize($idesc));
$posted = date("Y-m-d H:i:s");
$query = mysql_query("
INSERT INTO albums (description, posted, photos, name, descriptions, timestamp)
VALUES ('$desc', '$posted', '$images', '$name', '$descriptions', '$timestamp')
");
}
}
}
?>
I tried a simple thumbnail script found on this tutorial and it worked perfectly: http://net.tutsplus.com/articles/news/how-to-dynamically-create-thumbnails/
Thanks for your suggestions
You can use the Thumbnail class from
http://freecode.com/projects/easyphpthumbnailclass
You may use ImageMagick's resizeImage method.
explained in a tutorial here http://coffeeshopped.com/2009/01/creating-image-thumbnails-using-php-and-imagemagick
Also, you may try phpThumb() function and is available at sourceforge here http://phpthumb.sourceforge.net/
Hope this helps..
I want to select four random images from a folder which contains a number of images.
What i want to display is a table (2x2) where i can display 4 random distinct images.
Can someone tell me how can i select random distinct files from a folder so that i can store their path in a variable and then can use these variables to display images randomly in the table!
Is there any particular function which can select random files from a folder or something like that?
Use glob() to get all files from directory.
Use array_rand() to get random entries from an array.
<?php
function get_imagess($root) {
$r = array();
$r = array();
$k = glob("$root/*");
shuffle($k);
foreach($k as $n) {
if (is_dir($n)) {
break;
//$r = array_merge($r, get_imagesss($n));
print_r("xxx");
} else {
$r[] = $n;
//print_r($n + "yeah");
}
}
return $r;
}
function get_images($root) {
$r = array();
$k = glob("$root/*");
shuffle($k);
$n = $k[0];
// foreach($k as $n) {
if (is_dir($n)) {
$r = array_merge($r, get_imagess($n));
} else {
$r[] = $n;
}
// }
return $r;
}
$files = get_images('.');
//print_r($files);
//break;
shuffle($files);
$true=true;
$extList = array();
$extList['gif'] = 'image/gif';
$extList['jpg'] = 'image/jpeg';
$extList['jpeg'] = 'image/jpeg';
$extList['png'] = 'image/png';
$ass=0;
while($true)
{
$ass=$ass+1;
if($ass>100){$true=false;}
$imageInfo = pathinfo($files[0]);
if (isset( $extList[ strtolower( $imageInfo['extension'] ) ] )){
$temp = substr($files[0], -5);
$temp = strtolower($temp);
if( $temp == "p.jpg"){shuffle($files);} // checking if jpg has a preview file
else{ // no preview found
$true=false;
//print_r($temp);
}}
else
{
shuffle($files);
//print_r('bad' + $temp);
}
}
//print_r($files[0]);
echo '<HTML><meta HTTP-EQUIV="Refresh" CONTENT="5; URL=./ImageRotateMaybe.php"><img src="';
echo $files[0];
echo ' " width=100%>';
?>