I have tried many hours just to get this tiny piece of information to show, I need help before I decide to brake my laptop in two pieces.
I am trying to get an uploaded image to display a caption along with username (person who uploaded it) and date. These three values are stored in my database, the upload works fine. As I loop through the directory to display my images, I cannot get these values (passed as variables) to display correctly, rather the last upload input is the only one that displays for every image in my gallery.
I assume there is something wrong in my loop code and will post it here in hope that it is a simple overlooked fact.
//Open directory
$dir_handle = opendir($thumb_dir) or die('Error opening thumbnail directory.');
while ($file = readdir($dir_handle)) { //go through files
//if ($file == '.' || $file == '..') continue;
$file_parts = explode('.', $file); //split filename and put extensions in array
$ext = strtolower(array_pop($file_parts)); //last element file extension
//Filename w/o extension.
$title = implode('.', $file_parts); //only filename
$title = htmlspecialchars($title); //security measure
$dbconnect = mysqli_connect('localhost', 'peter', '1234', 'dt091g');
$query = 'SELECT username, date FROM image_info';
$result = mysqli_query($dbconnect, $query);
while ($row = mysqli_fetch_assoc($result)){
$username = $row['username'];
$date = $row['date'];
}
//add every image if good extension
if (in_array($ext, $allowed_exts)) {
echo '<a class="example-image-link"
href="'.$img_dir.$file.'"
data-lightbox="example-set"
data-title="'.$username.$date.'">
<img class="example-image" src="'.$thumb_dir.$file.'" alt="hello"/>
</a>';
$i++; //increment the image counter
}
}
closedir($dir_handle); ?>
I am assuming I must incorporate the unique ID somehow, and I have tried myself blind, but still end up with only the last value for any row of my db table.
Appreciate any kind of input, even if you're just writing to say 'Duh! You idiot'.
EDIT: Showing a record of image_info
$image_info = array( array('id' => '50','username' => 'Peter','date'
=> '05052015','filename' => '20140808_220541.jpg','mimetype' => 'image/jpeg','filesize' => '2404856','caption' => 'Norwegian
Mountains'));
Related
I searched Google all over the place for an answer but I can't seem to find the right one so I'll try it here.
I want to store the users' firstname, lastname and the path of the images in the mysqli database and the image in the folder uploads. (the user can upload multiple images)
This works and is no problem.
The issue is:
When for example they type their firstname and lastname and select two images and press the upload button it uploads everything but it also creates two rows with the exact same values.
I want to store everyting in one row, see my code below:
<?php
$con = mysqli_connect('localhost','root','','img_db');
mysqli_select_db($con,'img_db');
$rn = mt_rand();
if(isset($_POST['submit'])&& isset($_FILES['image'])&& !empty($_POST['firstname'])&& !empty($_POST['lastname']))
{
$firstname = $_POST['firstname'];
$lastname = $_POST['lastname'];
for($i=0; $i<count($_FILES['image']['name']); $i++)
{
$tmp_name = $_FILES['image']['tmp_name'][$i];
$max_size = 100000;
$path = "uploads/";
$name = $_FILES['image']['name'][$i];
$size = $_FILES['image']['size'][$i];
$type = $_FILES['image']['type'][$i];
$ext = strtolower(substr($name, strpos($name, '.') +1));
$name = str_replace('_','',trim($name));
$name = str_replace('-','',trim($name));
$name = str_replace(' ','',trim($name));
$name = str_replace('__','',trim($name));
if(($ext=='jpg' || $ext=='jpeg' || $ext=='png' || $ext=='gif')&&($type=='image/jpeg' || $type=='image/png' || $type=='image/gif')&&$size<=$max_size)
{
if(move_uploaded_file($_FILES['image']['tmp_name'][$i], $path.$rn.$name))
{
mysqli_query($con,"INSERT into `img` (firstname,lastname,url) VALUES('$firstname','$lastname','$rn$name')");
}
}// END EXT
}// END FOR LOOP
}// END IF ISSET POST SUBMIT
?>
Suggestion 1
One solution is to store uploaded file urls in an array (declared before the for loop) and utilize the array outside of the for loop, like so:
if (isset(/* ... */)) {
// Outside your for loop
$files = array();
for (/* .. */) {
// Doing things
if (/* $ext stuff */) {
if (move_uploaded_file(/* ... */))
{
$files[] = $rn.$name;
}
} // End EXT
} // End FOR
// Utilize $files array to determine how you want to store all of these URLs in one field.
// Let's say you created a variable called $store with the desired representation.
mysqli_query($con,"INSERT into `img` (firstname,lastname,url) VALUES('$firstname','$lastname','$store')");
} // End ISSET
Suggestion 2
You could use a two-table structure (one table is users, one table is images) and create a foreign key relation from each image table row to a user table row via the desired user's primary key.
See: http://dev.mysql.com/doc/refman/5.6/en/create-table-foreign-keys.html
I have two tables:
first and parent "register"
and second is
What I wanted is to create a script in which one User with unique SN whenever upload a pic that pic path save in "userimg" i user SN as foreign key in userimg
code is below
if(isset($_POST['SN']))
{
$filename = $_FILES['upload_image']['name'].$user_SN;
$filesize = $_FILES['upload_image']['size'];
$filetype = $_FILES['upload_image']['type'];
$target_path ="uploads/". basename( $filename );
if (move_uploaded_file($_FILES['upload_image']['tmp_name'], $target_path))
{
$result = $target_path ;
$sql="INSERT INTO userimg (src, size, type,SN ) VALUES ('".$result."', '".$filesize."','".$filetype."','".$user_SN."')";
echo $sql." ";
echo $filesize." ";
echo $filetype." ";
$inst=mysql_query($sql);
if (!$inst)
{
print "error";
}
}
}
This script is working for one picture but what I want is like multiple uploads (just like a gallery) by user and saving that path in my second table.
Do I need to create a userimg table for each SN means user? What am I missing?
[EDIT]
Problem solved. Mistake was Making SN in userimg a unique and i rename image like this(code is below ) - Thankx Tuhin!
if(isset($_POST['SN']))
{
$filename = $_FILES['upload_image']['name'];
$filesize = $_FILES['upload_image']['size'];
$filetype = $_FILES['upload_image']['type'];
$timeSt = time();
$info = pathinfo($filename);
$name = $info['filename'];
$format = $info['extension'];
$target_path ="uploads/".basename( $name )."_".$user_SN."_".$timeSt.".".$format;
}
If the same user (means same SN value) tries to upload the same image (means already uploaded by him with same image name in this app) then the 'src' column in the second table will be same. Also if the uploaded folder first image file will be replaced by the newer file. Thats why I proposed you to add time stamp and rename the uploaded image file and store it into the DB.
As the title says I'm wanting to change the image names stored in a database to md5 but keep the image extension, I had a go with the code below but it failed (probably due to the fact I haven't a clue what I'm doing) ...any ideas on how I could achieve my goal?
function get_file_extension($file_name) {
return substr(strrchr($file_name,'.'),1);
}
$query = "SELECT img FROM post";
$result = mysql_query($query);
while($row = mysql_fetch_array($result)) {
$name = substr($row['img'], -4, 4);
$ext = get_file_extension($row['img']);
$notmd5 = $row['img'];
$md5img = md5($name).'.'.$ext;
$q = "UPDATE post SET img='$md5img' WHERE img='{$notmd5}'";
$r = mysql_query($q) or die(mysql_error());
}
..........................................................
Update
Answer:
Rename files in dir/folder and db names at same time:
function get_file_extension($file_name) {
return substr(strrchr($file_name,'.'),1);
}
//path to directory to scan
$directory = "thumbs/";
$directory2 = "md5/";
//get all image files with a .jpg extension.
$images = glob($directory . "*.*");
//print each file name
foreach($images as $image)
{
$imag = str_replace($directory, '', $image);
$ex = get_file_extension($imag);
$new = md5($imag).'.'.$ex;
rename($image, $directory2.$new);
$q = "UPDATE post SET img='$new' WHERE img='{$imag}'";
$r = mysql_query($q) or die(mysql_error());
}
When I originally asked my question I had already renamed the images in dir/folder but I had a backup of them so mixed the to jobs together and got my goal :)
First off, I'd recommend a batch update like this just be done with pure SQL, especially if the business logic is as simple as this, it can all be done natively in MySQL for sure.
Anyway.., one thing that pops out is the substr call to get the $name of the file, it's hardcoded to get only 4 characters and it's actually getting the extension not the name.
Try this instead:
$ext = get_file_extension($row['img']); // get ext first
// use length of $row['img'] - length of file extension to extract name
substr($row['img'], 0, strlen($row['img']) - strlen($ext) - 1);
Just do it in pure SQL:
UPDATE post SET img = CONCAT_WS('.',
MD5(TRIM(TRAILING CONCAT('.', SUBSTRING_INDEX(img, '.', -1)) FROM img)),
SUBSTRING_INDEX(img, '.', -1)
)
I'm trying to delete photos from a folder, which is called, "photos", that are NOT currently in my database. (These are all photos that have stacked up as I've been building the website and testing it and such, so now it's time to take the site live and I don't want all this waste in it)
I have three tables with photo information in them, and a number of columns throughout. Below is a mockup query of about what I THINK it should look like.
SELECT left_image, right_image, photo1, photo2, photo3, photo4, home_photo
FROM about_photos, facilities, home
left_image and right_image go with about_photos.
photo1, photo2, photo3 and photo4 go with facilities.
home_photo goes with home.
Also, I need to use a wildcard for the end of the photo, because the files have thumbnails, so for instance the original photo would be called, abcimage.jpg but there would be abcimage.jpg, abcimage_medium.jpg, abcimage_thumb.jpg also in the database I only store, photos/abcimage and add the rest of the filename depending on where it goes.
$directory = "../path/to/photos_directory/";
//get all image files with a .jpg extension.
$images = glob($directory . "*.jpg");
foreach($images as $image)
{
$name = explode('_',$image);
$name = 'photos/' . $name[0];
$sql = mysql_query("SELECT id FROM table WHERE photo1='$name' OR photo2='$name'");
if(mysql_num_rows($sql) == 0)
unlink($directory . $image);
}
You have two options:
One:
With an SQL query, get a complete list of all the photos referenced in your database
iterate through the files in your directory
if the file is an image AND it is not in your list, delete the file.
Two:
iterate through the files in your directory
if the file is an image
query the database for that filename
if the response is empty, delete the file
The exact SQL query depends on your table structure, which you have not provided.
The best option depends mostly on scale. If there are lots of images in the database, then the first option involves having a very large list in memory. However the second version involves many more database queries. So it's a tradeoff.
There are more sophisticated options involving caching and pre-emptive queries, but I imagine you don't want to go that deep yet.
Something like the following. I've also got original files in the folder and I limit to 500 deletions at a time. Tweak as you need. Hope it saves somebody time...
<?php
require 'session.php';
require 'settings.php';
/* Execute the query. */
$DBH = new PDO($mssql_driver.'='.$mssql_server.';'.$mssql_dbkey.'='.$mssql_database, $mssql_username, $mssql_password);
$DBH->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
$tsql = 'select * from ProductImage';
$PRE = $DBH->prepare($tsql);
$PRE->execute();
$pictures =$PRE->fetchAll(PDO::FETCH_ASSOC);
$directory = $_SERVER["DOCUMENT_ROOT"]."\..\..\products\pictures/";
//get all image files with a .jpg extension.
$images = glob($directory . "*.jpg");
$counter =0;
foreach($images as $image)
{
$name = explode('pictures/',$image);
$name = $name[1];
$foundImage = false;
print "checking: ".$name;
foreach ($pictures as $picture){
$original_file = explode('.', $picture['Image_Big']);
$original_file = $original_file[0].'-original.'.$original_file[1];
if ( ($picture['Image_Small'] == $name)|| ($picture['Image_Big'] == $name) || ( $original_file == $name) || ($picture['Image_Thumb'] == $name) || ($picture['Image_PriceList'] == $name)){
$foundImage = true;
break;
}
}
if (!$foundImage) {
unlink($directory . $name);
print "....deleting";
$counter += 1;
}
print "<br />";
if ($counter> 500){
exit;
}
}
?>
I have this function: http://pastebin.ca/2058418
It basically checks to see if a tables contains some URLs to pictures of a band. If it does, then it will order the table by random, choose the first result and then output the html code to insert the picture. If the table does not have the pictures of that specific band, then it downloads an XML file which contains the image URL's, parses the XML and inserts in into the table, and then gets the HTML code for the image like before.
In terms out html output, you can't tell if the image URL has been cached or not. HOWEVER, when the image URL is cached (for the first time), whatever web browser you use will not display the image. The HTML is fine - the image is linked correctly.
Do you have any ideas? A live version of the site which contains this function is here: http://redfern.me/similar/. I have just emptied the tables, so there shouldn't be many cached URL's. Try choosing a band, and then see if the image loads. You can tell if the URL's where cached or not by looking at the bottom of the page.
basically looks like you wasn't returning after you fetched the image first time.
<?php function getimage($artist){
$api_key = "XXXXXXXXX";
$iquery = mysql_query("SELECT url FROM `images` WHERE artist = '".$artist."' ORDER BY RAND() LIMIT 1");
if($artist != ""){
$artist = str_replace(" ", "+", $artist);
if(mysql_num_rows($iquery) == 0){
$url = "http://developer.echonest.com/api/v4/artist/images?format=xml&api_key=".$api_key."&name=".$artist."&results=20";
$data = file_get_contents($url);
if($data=false){return 'Error Getting Image';}
$images = new SimpleXMLElement($data);
foreach($images as $image){
foreach($image->image as $indimage){
$insiquery = "INSERT INTO images (id, artist, url) VALUES (NULL, '$artist','".$indimage->url."')";
mysql_query($insiquery);
}
}
return "<img src=\"".$indimage->url."\" alt=\"$artist image\" />";
}else{
$imgurl = mysql_fetch_array($iquery);
return"<img src=\"".$imgurl['url']."\" alt=\"$artist image\" />";
}
}
else{
return"Image Aquire Function Error: <i>No Band Specified</i>";
}
return null;
}?>
echo getimage('Britney Spears');
That's simply because when you enter to the "xml call" your var "$imgurl[0]"
is empty :
try something like this :
$images = new SimpleXMLElement($data);
$xmlImgUrl = array();
foreach($images as $image){
foreach($image->image as $indimage){
$xmlImgUrl[] = $indimage->url;
$insiquery = "INSERT INTO images (id, artist, url) VALUES (NULL, '$artist','".$indimage->url."')";
mysql_query($insiquery);
}
}
}
$imgurl = $nrows == 0 ? $xmlImgUrl : mysql_fetch_row($iquery);
if(!empty($imgurl)) echo "<img src=\"".$imgurl[0]."\" alt=\"$artist image\">";
which instantiate an array of image urls when no results in mysql.