Images upload in the wrong order - php

I am aware it's an old script (an old way of doing things). The script works, however, the images do not upload in the right order. I am not exactly sure but it looks to me they upload from last to first instead of from first to last. What makes it do that?
if (count($_FILES['pic']['tmp_name']))
{
$ipval = ipval();
$uploaderror = 0;
$uploadcount = 0;
$errorMessages = array();
foreach ($_FILES['pic']['tmp_name'] as $k=>$tmpfile)
}
if ($tmpfile)
{
$thisfile = array("name"=>$_FILES['pic']['name'][$k],
"tmp_name"=>$_FILES['pic']['tmp_name'][$k],
"size"=>$_FILES['pic']['size'][$k],
"type"=>$_FILES['pic']['type'][$k],
"error"=>$_FILES['pic']['error'][$k]);
if ($_FILES['pic']['size'][$k] > $pic_maxsize*1000)
{
$errorMessages[] = $thisfile['name'] . " - " . $lang['ERROR_UPLOAD_PIC_TOO_BIG'];
$uploaderror++;
}
elseif (!isValidImage($thisfile))
{
$errorMessages[] = $thisfile['name'] . " - " . $lang['ERROR_UPLOAD_PIC_BAD_FILETYPE'];
$uploaderror++;
}
else
{
$newfile = SaveUploadFile($thisfile, "{$path_escape}{$datadir['adpics']}", TRUE, $images_max_width, $images_max_height);
if($newfile)
{
$sql = "INSERT INTO $t_adpics
SET adid = $adid,
picfile = '$newfile'";
mysql_query($sql);
if (mysql_error())
{
...

If by "order" you mean the order that you selected the images in a multiple file input, you cannot rely on that order being consistent on the back end. It varies by browser and server: does multiple upload follow the same order of uploading in which we select the images?
If you are always seeing the order reversed, perhaps you need to change some code in the script that serves them up (ASC instead of DESC).
One way you could keep the order consistent is by sending another variable to the server on upload that contains an array of the file names in order, then base your INSERT order off of that array, not the order of the $_FILES array.

Related

PHP: Fastest way to loop through a array / stringbuiler or something else

We have a PHP script that loops through many XML / CSV files from different websites. Right now we manage to build a good XML / CSV parser script.
The PHP script we wrote is looping though some BIG XML or CSV files. In these XML or CVS files contains Barcodes from different products.
Right now before the script starts I fill an array with the Product ID + Barcode from the MySQL like this:
function Barcodes_Array() {
$sql = "SELECT ProductId, Barcode FROM Products WHERE (Barcode <> '') ";
$res = mysql_query($sql);
while ($rijen = mysql_fetch_assoc($res)) {
$GLOBALS['arrBarcodes'][] = $rijen;
}
}
Each time we loop through the XML (or CSV) files we have to check if the Barcode exists in the array and return the Product ID.
For searching in the function:
$ProductId = SearchBarcodeProduct($EanNr, 'Barcode');
And yet the function:
function SearchBarcodeProduct($elem, $field)
{
$top = sizeof($GLOBALS['arrBarcodes']) - 1;
$bottom = 0;
$ProductId = 0;
while($bottom <= $top)
{
if($GLOBALS['arrBarcodes'][$bottom][$field] == $elem) {
return $GLOBALS['arrBarcodes'][$bottom]['ProductId'];
}
else {
if (is_array($GLOBALS['arrBarcodes'][$bottom][$field])) {
if (in_multiarray($elem, ($GLOBALS['arrBarcodes'][$bottom][$field]))) {
return $GLOBALS['arrBarcodes'][$bottom]['ProductId'];
}
}
}
$bottom++;
}
return $ProductId;
}
We fill in the array because it took forever each time we ask the MySQL Products Table.
My Question is now:
It still takes a VERY long time each time looping through the array of the barcodes. Is there a faster way for any other solutions maybe a different way then a array?
Can someone help please i am working like weeks on this stupid :) thing!
Why do you need 2 functions?
Try just one
function itemBarcode($id) {
$id = intval($id);
$sql = "SELECT ProductId, Barcode FROM Products WHERE ProductId = $id Barcode <> '') ";
$res = mysql_query($sql);
if ($row = mysql_fetch_assoc($res)) {
return $row['barcode'];
} else {
return 0;
}
}
Update if you need to search by barcode you can create another function:
function itemProduct($barcode) {
$sql = "SELECT ProductId, Barcode FROM Products WHERE Barcode = $barcode ";
$res = mysql_query($sql);
if ($row = mysql_fetch_assoc($res)) {
return $row['ProductId'];
} else {
return 0;
}
}
Sounds like you are missing an index on your Barcode column in your database.. A single row lookup using a presumably unique single indexed column should be blisteringly fast.
CREATE INDEX Barcode_Index ON Products (Barcode)
Then simply:
SELECT ProductId FROM Products WHERE Barcode = *INPUT*
You could also make the index UNIQUE if you NULL the Barcode where they currently = '' if there are more than one of these.
Another option is keying the array you have with the Barcode:
while ($rijen = mysql_fetch_assoc($res)) {
$GLOBALS['arrBarcodes'][$rijen['Barcode']] = $rijen;
}
or even just:
while ($rijen = mysql_fetch_assoc($res)) {
$GLOBALS['arrBarcodes'][$rijen['Barcode']] = $rijen['ProductId'];
}
Then you can do a straight look up:
$ProductId = isset($GLOBALS['arrBarcodes'][$Barcode])
?$GLOBALS['arrBarcodes'][$Barcode]['ProductId']
:0;
or:
$ProductId = isset($GLOBALS['arrBarcodes'][$Barcode])
?$GLOBALS['arrBarcodes'][$Barcode]
:0;
N.B Please read the warnings in the comments about use of $GLOBALS and mysql_query.
If you need it, store the barcodes array in an object or variable instead.
PDO is pretty handy, and I think it can also key your returned array for you on fetch.

Set a limit in the results (no mysql)

Can I put a limit to show in a list of images extracted from a folder? I should point out that I do not mean with mysql but simple php.
Practically from a folder I extract all the images, here, I would like to set a limit. is it possible? or must necessarily the database?
You mention "extracted from a folder" and also "or must necessarily the database" so I'm not sure what your source is.
If you are getting the list of images them from a folder, presumably using something like glob() or readdir() or scandir() then you end up with an array. If you only want to display a certain number of those images then simply stop after that number of iterations...
$imgs = glob('*.jpg');
$count = 0;
foreach ($imgs as $img) {
if ($count++ > 20) break; // place a limit of 20
echo "<img src='$img' alt='$img' />\n";
}
If you are using a database to obtain your list of image filenames then you would do something similar, controlling it within your loop:
$sql = "SELECT filename, alt_text FROM ...";
$conx = mysqli_connect($host, $user, $pass, $dbname, ...);
$results = mysqli_query($conx, $sql);
$count = 0;
while ($row = mysqli_fetch_assoc($conx, $results)) {
if ($count++ > 20) break; // place a limit of 20
echo "<img src='$row[filename]' alt='$row[alt_text]' />\n";
}
mysqli_free_results($results);
If I have not yet answered your question then please clarify. If I have, please vote for the answer.
Thanks!
Try
array_slice(scandir($dir), 0, $limit);

Cannot get result when passing php variable to mysql query

I am trying to pass a part of a file name as a parameter in the my sql query in php. My file name is in the form
db_feature_T1..iOXXdrXXcAMEra_092521.txt
from which I want the part except the db_feature and .txt i.e.
T1..iOXXdrXXcAMEra_092521
I want the img_id from the database whose img_path=dressimages/T1..iOXXdrXXcAMEra_092521.jpg
My code is as follows.I was able to seperate the file name but I cannot get any result from the database.
<?php
include('db.php');
if ($handle = opendir('C:\Users\adithi.a\Desktop\db_features')) {
while (false !== ($entry = readdir($handle))) {
$entry=substr($entry,11,-4); //this seperates the file name db_feature_T1..iOXXdrXXcAMEra_092521.txt to T1..iOXXdrXXcAMEra_092521
$image_path='dressimages/'.$entry.'.jpg';//I want to pass the img_path as it is saved in the database in the form of dressimages/T1..iOXXdrXXcAMEra_092521.jpg
$result= mysql_query("select img_id from tbl_image where img_path='$image_path'") or die("Sorry");
echo $result;//I dont get anything as output.
}
}
closedir($handle);
?>
I went to an infinite loop when executing the code above so i tried:
$image_path='dressimages/'.$entry.'.jpg';//I want to pass the img_path as it is saved in the database in the form of dressimages/T1..iOXXdrXXcAMEra_092521.jpg
$sql = "select img_id from tbl_image where img_path=".$image_path;
echo $sql . '<br />';
$result=mysql_query("$sql");
}
while($data=mysql_fetch_assoc($result))
{
echo $data["img_id"];
}
and Now i get the error mysql_fetch_assoc() expects parameter 1 to be resource, boolean given in C:\wamp\www\FashionBonanza\Readfile.php on line 34
Any help
You have to first fetch the data from your result
$data=mysql_fetch_assoc($result); // this is missing
print_r($data); // or
echo $data["img_id"];
and in case there can be multiple results you can do so in a loop
while($data=mysql_fetch_assoc($result))
{
print_r($data); // or
echo $data["img_id"];
}
Because you're dealing with so many files I would try another approach. That would be to store all paths into an array, make a single query and associate id's with path's. I'm not sure this code will work (I haven't tested it), but I hope you get the picture:
<?php
include('db.php');
if ($handle = opendir('C:\Users\adithi.a\Desktop\db_features')) {
//Store all paths into $image_paths array
$image_paths = array();
while (false !== ($entry = readdir($handle))) {
$entry=substr($entry,11,-4); //this seperates the file name db_feature_T1..iOXXdrXXcAMEra_092521.txt to T1..iOXXdrXXcAMEra_092521
if (strlen($entry) !== 0) {
$image_paths[]='dressimages/'.$entry.'.jpg';//I want to pass the img_path as it is saved in the database in the form of dressimages/T1..iOXXdrXXcAMEra_092521}
}
}
closedir($handle);
//Implode paths
$pathQuotesArray = array_map('apply_quotes', $image_paths); //Looks like 'filename1', 'filename2' etc
$pathQuotes = implode(',', $pathQuotesArray);
//Do one query
$result= mysql_query("select img_id from tbl_image WHERE img_path IN ($pathQuotes)") or die(mysql_error());
//Associate id's with paths
while($data=mysql_fetch_assoc($result))
{
$key[$data["img_id"]] = $data["img_path"];
}
echo $key[5]; //If img_id is 5, then it would show correct path (hopefully :-))
function apply_quotes($item)
{
return "'" . mysql_real_escape_string($item) . "'";
}
?>
Try this
$result= mysql_query("select img_id from tbl_image where img_path="$image_path) or die("Sorry");
Just two ideas:
$result= mysql_query("select img_id from tbl_image where img_path='".$image_path."'") or die("Sorry");
Maybe it's better to do it this way. Otherwise set a extra string variable for the SQL-query, so you can track the exact query, which was executed.
$sQry = "select img_id from tbl_image where img_path='".$image_path."'";
var_dump($sQry);
$result= mysql_query($sQry) or die("Sorry");
So you can check, if the variable contains the correct value or not.
Next point is the "echo". You can't echo a result set, use functions like mysql-fetch-array() or mysql_fetch_assoc() - http://php.net/manual/de/function.mysql-fetch-array.php - or other ones.
while ($row = mysql_fetch_assoc($result)) {
echo $row["img_id "];
}

Delete files that are not in my database

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;
}
}
?>

foreach() not "for eaching" items in array PHP

if I do this, it works:
$data_array2 = mysql_query("SELECT pic_loc FROM pictures WHERE user_id = '".$id."'");
$cell_pictures = mysql_fetch_array($data_array2);
foreach($cell_pictures as $pics_being_deleted)
{
unlink($pics_being_deleted);
}
Problem being is that the above code is nested meaning it runs a new MySQL query for each time it runs the unlink function so I made the below code to make it not do that:
$the_pics_raw_2 = array();
$data_array2 = mysql_query("SELECT pic_loc FROM pictures WHERE user_id = '".$id."'");
while($cell_pictures = mysql_fetch_array($data_array2))
{
$the_pics_raw = $cell_pictures['pic_loc'];
$the_pics_raw_2[] = $the_pics_raw;
}
$the_pics_raw_3 .= " \"../../". implode("\" , \"../../" ,$the_pics_raw_2)."\"";
$the_pics = array($the_pics_raw_3);
foreach($the_pics as $pics_being_deleted)
{
unlink($pics_being_deleted);
}
I get this error in return:
Warning: unlink( "../../users/biondizzle/photos/pic_3387677.png" , "../../users/biondizzle/photos/pic_1581185.png") [function.unlink]: No such file or directory
it's obviously not going to find the "../../users/biondizzle/photos/pic_3387677.png" , "../../users/biondizzle/photos/pic_1581185.png" directory because that's 2 separate directories running at the same time so the foreach() isn't "foreaching".
Any way to get the unlink() to run separately for each directory i have listed in the array, I thought I would get it to work by adding the commas and quotations with the implode()?
Thanks a bunch, hope I explained it well enough
-Mike
I think this is what you want to do:
while($cell_pictures = mysql_fetch_array($data_array2)) {
$the_pics_raw = $cell_pictures['pic_loc'];
$the_pics[] = "../../" . $the_pics_raw;
}
foreach($the_pics as $pics_being_deleted) {
unlink($pics_being_deleted);
}
You will notice I have removed the $the_pics_raw_3 .= " \"../../". implode("\" , \"../../" ,$the_pics_raw_2)."\""; line as it was converting the array into a string, which was making it impossible to then foreach over.
Use this code:
$the_pics_raw = array();
$data_array2 = mysql_query("SELECT pic_loc FROM pictures WHERE user_id = '".$id."'");
while($cell_pictures = mysql_fetch_array($data_array2))
{
array_push($the_pics_raw,"../../".$cell_pictures['pic_loc']);
}
foreach($the_pics as $the_pics_raw)
{
unlink($pics_being_deleted);
}

Categories