delete image from row that has been expired - php

Hey I have a php code that checks which rows date got expired and delete them , one of the columns is an image name that was uploaded to the server via ftp, when I delete all expired records I also want to delete the images that is attached to them.
I read about the unlink command on php but I don't see how I can apply it to all of the images at once.
I have this code that I just rambled for example cause I don't really know how to do it..
$sql = "DELETE FROM table WHERE date < NOW()";
mysqli_query($conn,$sql);
$file = "public_html/images/".//Here should go the image name;
unlink($file);
if($sql)
{
echo "Records were deleted";
}
?>
Can anyone tell me how can I delete all images that are attached to the deleted rows?

IF you want to delete the rows from the table in your database and at the same time delete the images from the folder on the server where you keep them then you will have to process each delete candidate one at a time, so that you can get the filename from the row to accomplish the file delete at the same time sa deleting the row.
// connect to database
$base_path = 'public_html/images/';
$del_count = 0;
// SELECT all the delete candidates
$sql = "SELECT id,image FROM table WHERE date < NOW()";
$sel4del = mysqli_query($conn,$sql);
if ( ! $sel4del ) {
echo $sel4del->error;
exit;
}
// prepare a delete by id
$sql = 'DELETE FROM table WHERE id = ?';
$delrow = mysqli_prepare($conn,$sql);
if ( ! $delrow ) {
echo $delrow->error;
exit;
}
// Process all the delete candidates one by one
while ($row = $sel4del->fetch_object() ) {
// remove the file from disk
unlink($base_path . $row->image);
$del_count++;
// bind the current id to the prepared delete query
$delrow->bind_param('i', $row->id);
// execute the delete of this one row
$delrow->execute();
}
echo 'images removed = ' . $del_count
?>

Related

php script for selecting/inserting, only succeeds for one row

I made a fairly simple script to take records from a development database, and for each selected record insert it into production and get the newly created ID.
This "Works" but only for one record. WHen I run this script, it successfully connects, selects, inserts, and prints the newly inserted record's ID but then the script just stops and when I check the database only one new record is there, even though there are over 500 records in the source table
Is it just becuase I'm using While instead of foreach? I think I've done something similar before with a while loop but this isjust dying on me after one successful attempt.
if($DB2connDEV && $DB2connPROD){
$getDevelopment = "
SELECT * FROM TEST_TABLE; // there are over 500 records in here
";
$stmt = odbc_exec($DB2connDEV, $getDevelopment);
while($gettingDevelopment = odbc_fetch_array($stmt)){
$originalID = $gettingDevelopment['identity'];
$insertTable = "INSERT INTO testing_insert_php (name) VALUES ($originalID)";
$getIdentity = "SELECT IDENTITY_VAL_LOCAL() AS LASTID FROM SYSIBM.SYSDUMMY1";
$stmt = odbc_exec($DB2connPROD, $insertTable);
$stmt = odbc_exec($DB2connPROD, $getIdentity);
$row = odbc_fetch_array($stmt);
$ret = $row['LASTID'];
if($ret) {
echo "Last Insert ID is : " . $ret . "\n";
} else {
echo "No Last insert ID.\n";
}
}
odbc_close($DB2connPROD);
}

Delete file from folder and mysql joined table

I have a file upload system where I can delete from MySQL DB and from the folder.
The only problem is that all the files in the folder are deleted instead of just the single one. Each folder is a custom folder with a person's name.
I have a joined table where the id's of two tables are equal. I need the joined tabled to receive the name of the person to know the file location.
This is my working code so far where multiple files are deleted instead of the one I selected:
$analyse = mysqli_query($conn, "SELECT *
FROM analyse
INNER JOIN persons ON
analyse.id_person = persons.id");
while ($row = mysqli_fetch_array($analyse)) {
$img = $row['img_name'];
$name= $row['name'];
$frontname= $row['frontname'];
$image_url = "../persons/{$name} {$frontname}/analyse/{$img}";
$result = mysqli_query($conn, "DELETE FROM analyse WHERE id=$id");
unlink($image_url);
if($result){
header('Location: ' . $_SERVER['HTTP_REFERER']);
} else {
echo "Failed to delete";
}
}
For example: Person X with id 15 has three images with different ids but each time with the ID(15) of the person. I want to be able to delete the single selected file instead of all the files with id 15.
UPDATE
I found the solution, the ID that came through for deleting was always the first in my DB row. The fetching of my array was wrong and my ID consequently too.
Thanks for the answers.
Try using Limit 1 with your delete Query.
$analyse = mysqli_query($conn, "SELECT *
FROM analyse
INNER JOIN persons ON analyse.id_person = persons.id");
while ($row = mysqli_fetch_array($analyse)) {
$img = $row['img_name'];
$name= $row['name'];
$frontname= $row['frontname'];
$image_url = "../persons/{$name} {$frontname}/analyse/{$img}";
$result = mysqli_query($conn, "DELETE FROM analyse WHERE id=$id LIMIT 1");
unlink($image_url);
if($result){
header('Location: ' . $_SERVER['HTTP_REFERER']);
} else {
echo "Failed to delete";
}
}

Deleting row from the Database and the table

I am new to PHP so please dont go mad on me for this.
I am trying to delete rows from table but an notice is coming that :-
Notice: Undefined variable: id in A:\PHP\htdocs\0\delete.php on line 5
Record deleted successfully
But the record is not getting deleted from the table and database.
<?php
require('connect.php');
$sql = "DELETE * FROM upload WHERE id='$id'";
$result = mysql_query($sql);
if ($result) {
echo "Record deleted successfully";
} else {
echo "Error deleting record: " . mysql_error();
}
?>
this will work for you
$id='3'; //any id you want to delete
$query = "DELETE FROM `upload` WHERE `id` = '$id'";
To delete a record no need to use DELETE * FROM you can use DELETE FROM.
The following query help you
$ids = array(3, 4);
$sql = 'DELETE FROM tableName WHERE `id` IN (implode(',', $ids));
Try out this.
Quite self explanatory, you don't have the variable $id set, this needs to be the id of the row, you should also remove the asterisk from your statement as this is not required when deleting
To delete all row just use
Delete * from upload

how can i move multiple files where the file names and paths are in columns of a database table?

files locations are stored in database, and when i delete the table records/rows from the files table, i need to move the files to another directory (an archive directory).
there are 2 tables at play. a jobs table and files table. jobs have files. when deleting a job i need to delete the job entry from jobs table, but also i need to delete file(s) entries from files table, but the actual files are not be be deleted... they are to be moved (archived).
here is the entire delete script that is attempting to delete records from 2 tables and move files to another folder. the deleting of records from both tables works. only one file is moved though. if there are multiple files, it doesn't move all the files. i tried wrapping the rename line with a while line. i tried wrapping the entire if($dbrow) section in the same while clause. i can't get this to work with while to loop through all the files. maybe a foreach is in order? how can i do that?
<?php
/*
delete-job.php
Deletes job entry from the 'jobs' table and also deletes file entry/entries from 'files' table and moves (archives) files
*/
//check if the 'id' variable is set in URL, and check that it is valid
if (isset($_GET['id']) && is_numeric($_GET['id'])) {
//get id value
$id = $_GET['id'];
$dbresult = mysql_query("SELECT jobs.*, files.* FROM jobs INNER JOIN files WHERE files.jobid = jobs.id") or die(mysql_error());
$dbrow = mysql_fetch_array($dbresult);
if($dbrow) {
$name = $dbrow['name'];
$path = $dbrow['path'];
$count = $dbrow['count'];
$approved = $dbrow['approved'];
$approved_date = $dbrow['approved_date'];
$jobid = $dbrow['jobid'];
$timedateadded = $dbrow['timedateadded'];
$currentdate = date("m-d-Y_H-i-s");
$archivepath = "uploads/archive/".$name;
rename("".$path."", "".$archivepath."");
//delete the entry/entries
//$result = mysql_query("DELETE FROM jobs WHERE id=$id") or die(mysql_error()); //delete from just jobs table
$result = mysql_query("DELETE jobs, files FROM jobs INNER JOIN files WHERE jobs.id = $id AND files.jobid = jobs.id") or die(mysql_error()); //also delete file records from files table that belong to the deleted jobs
header("Location: view-jobs.php"); //redirect back to the view page
} //end if($dbrow)
} //end if isset
else { //if id isn't set, or isn't valid...
header("Location: view-jobs.php"); //redirect back to view page
}
?>
Is this what you want or did you try that already? (Edited)
<?php
if (isset($_GET['id']) && is_numeric($_GET['id'])) {
$id = $_GET['id'];
$dbresult = mysql_query("SELECT jobs.*, files.* FROM jobs INNER JOIN files WHERE files.jobid = jobs.id") or die(mysql_error());
while($dbrow = mysql_fetch_array($dbresult))
{
$name = $dbrow['name'];
$path = $dbrow['path'];
$count = $dbrow['count'];
$approved = $dbrow['approved'];
$approved_date = $dbrow['approved_date'];
$jobid = $dbrow['jobid'];
$timedateadded = $dbrow['timedateadded'];
$currentdate = date("m-d-Y_H-i-s");
$archivepath = "uploads/archive/".$name;
rename("".$path."", "".$archivepath."");
//delete the entry/entries
//$result = mysql_query("DELETE FROM jobs WHERE id=$id") or die(mysql_error()); //delete from just jobs table
}
$result = mysql_query("DELETE jobs, files FROM jobs INNER JOIN files WHERE jobs.id = $id AND files.jobid = jobs.id") or die(mysql_error()); //also delete file records from files table that belong to the deleted jobs
header("Location: view-jobs.php"); //redirect back to the view page
}else { //if id isn't set, or isn't valid...
header("Location: view-jobs.php"); //redirect back to view page
}
?>

There has got to be a more efficient way to do this

Basically I am trying to trim the images table down to 3,500 rows of unsaved or unfiltered images. Unsaved and unfiltered refer to other tables in the DB. A user can save an image as well as mark an image safe for work etc... I would like to keep all images in the saves table as well as the filter table.
Ultimately, The images table will get trimmed down to (3,500 unsaved/unfiltered images) + ("X" saved)+("X" unfiltered). The link between saves/filters/images is the auto_incremented id given to the record in the images table. So saves has an image_id field that gets the key of the record in the images table. same with the filters table
//connect to database
$connect = xxxxxxxxxxx;
//GET ALL IMAGES FROM `images` Table - NEWEST FIRST (`id` is auto_increment)
$sql = mysql_query("SELECT * FROM `images` ORDER BY `id` DESC") or die(mysql_error());
$x = 0;
while($row = mysql_fetch_array($sql)){
//GET CURRENT IMAGES ID AND URL
$id = $row['id'];
$file = $row['url'];
//SEE IF IMAGE IS IN THE saves Table
$saves = mysql_query("SELECT `id` FROM `saves` WHERE `img_id` = '".$id."'") or die(mysql_error());
if(mysql_num_rows($saves) == 0){$saved = FALSE;}
else {$saved = TRUE;}
//SEE IF IMAGE IS IN THE filters Table
$filter = mysql_query("SELECT `id` FROM `filter` WHERE `img_id` = '".$id."'") or die(mysql_error());
if(mysql_num_rows($filter) == 0){$filtered = FALSE;}
else {$filtered = TRUE;}
//If the image has not been saved or filtered then put it in a que for deletion
if(!$saved || !$filtered){
$IdQue[$x] = $id;
$FileQue[$x] = $file;
$x++;
}//END if
}//END while
//Process the delete que: Delete node from database, delete file on server. Keep 3,500 of the newest images.
for($i=3500; $i<$x; $i++){
mysql_query("DELETE FROM `images` WHERE id='".$IdQue[$i]."' LIMIT 1") or die("line 33".mysql_error());
if(file_exists($FileQue[$i])){
unlink($FileQue[$i]) or die("file Not deleted");
}//END if
}//END for
echo ($i-3500)." files deleted<br/>";
//terminate connection
mysql_close($connect);
this should get you going somewhere, not a complete code though:
first, strip selecting ids down to 2 queries:
$missing_from_filters = SELECT id FROM images WHERE img_id NOT IN (SELECT img_id FROM filter)
$missing_from_saves = SELECT id FROM images WHERE img_id NOT IN (SELECT img_id FROM saves)
then, get ids that are in both arrays
$to_delete = array_intersect($missing_from_filters,$missing_from_saves);
run one query to remove them all
$remove_query = 'DELETE FROM images WHERE img_id IN ( '.implode(',',$to_delete).') LIMIT 3500';

Categories